mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-09-26 20:00:27 +00:00
Merge pull request #4430 from fwolter/add-f1-remap
Add STM32F1 AFIO remap
This commit is contained in:
commit
25e0ebf520
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -17,7 +17,7 @@
|
|||||||
//"rust-analyzer.cargo.target": "thumbv8m.main-none-eabihf",
|
//"rust-analyzer.cargo.target": "thumbv8m.main-none-eabihf",
|
||||||
"rust-analyzer.cargo.features": [
|
"rust-analyzer.cargo.features": [
|
||||||
// Comment out these features when working on the examples. Most example crates do not have any cargo features.
|
// Comment out these features when working on the examples. Most example crates do not have any cargo features.
|
||||||
"stm32f446re",
|
"stm32f107rb",
|
||||||
"time-driver-any",
|
"time-driver-any",
|
||||||
"unstable-pac",
|
"unstable-pac",
|
||||||
"exti",
|
"exti",
|
||||||
|
6
ci.sh
6
ci.sh
@ -311,7 +311,9 @@ cargo batch \
|
|||||||
--- build --release --manifest-path examples/boot/bootloader/stm32wba-dfu/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-stm32/stm32wba65ri,verify \
|
--- build --release --manifest-path examples/boot/bootloader/stm32wba-dfu/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-stm32/stm32wba65ri,verify \
|
||||||
--- build --release --manifest-path examples/boot/bootloader/stm32-dual-bank/Cargo.toml --target thumbv7em-none-eabi --features embassy-stm32/stm32h743zi \
|
--- build --release --manifest-path examples/boot/bootloader/stm32-dual-bank/Cargo.toml --target thumbv7em-none-eabi --features embassy-stm32/stm32h743zi \
|
||||||
--- build --release --manifest-path examples/wasm/Cargo.toml --target wasm32-unknown-unknown --artifact-dir out/examples/wasm \
|
--- build --release --manifest-path examples/wasm/Cargo.toml --target wasm32-unknown-unknown --artifact-dir out/examples/wasm \
|
||||||
|
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f100rd --artifact-dir out/tests/stm32f100rd \
|
||||||
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f103c8 --artifact-dir out/tests/stm32f103c8 \
|
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f103c8 --artifact-dir out/tests/stm32f103c8 \
|
||||||
|
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f107vc --artifact-dir out/tests/stm32f107vc \
|
||||||
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi --artifact-dir out/tests/stm32f429zi \
|
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi --artifact-dir out/tests/stm32f429zi \
|
||||||
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f446re --artifact-dir out/tests/stm32f446re \
|
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f446re --artifact-dir out/tests/stm32f446re \
|
||||||
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g491re --artifact-dir out/tests/stm32g491re \
|
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g491re --artifact-dir out/tests/stm32g491re \
|
||||||
@ -398,8 +400,10 @@ rm out/tests/pimoroni-pico-plus-2/pwm
|
|||||||
rm out/tests/rpi-pico/pwm
|
rm out/tests/rpi-pico/pwm
|
||||||
rm out/tests/rpi-pico/cyw43-perf
|
rm out/tests/rpi-pico/cyw43-perf
|
||||||
|
|
||||||
# tests are implemented but the HIL test farm doesn't actually have this board yet
|
# tests are implemented but the HIL test farm doesn't actually have these boards, yet
|
||||||
rm -rf out/tests/stm32c071rb
|
rm -rf out/tests/stm32c071rb
|
||||||
|
rm -rf out/tests/stm32f100rd
|
||||||
|
rm -rf out/tests/stm32f107vc
|
||||||
|
|
||||||
if [[ -z "${TELEPROBE_TOKEN-}" ]]; then
|
if [[ -z "${TELEPROBE_TOKEN-}" ]]; then
|
||||||
echo No teleprobe token found, skipping running HIL tests
|
echo No teleprobe token found, skipping running HIL tests
|
||||||
|
@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- fix: Fix stm32h7rs init when using external flash via XSPI
|
- fix: Fix stm32h7rs init when using external flash via XSPI
|
||||||
- feat: Add Adc::new_with_clock() to configure analog clock
|
- feat: Add Adc::new_with_clock() to configure analog clock
|
||||||
- feat: Add GPDMA linked-list + ringbuffer support ([#3923](https://github.com/embassy-rs/embassy/pull/3923))
|
- feat: Add GPDMA linked-list + ringbuffer support ([#3923](https://github.com/embassy-rs/embassy/pull/3923))
|
||||||
|
- feat: Added support for STM32F1 peripheral pin remapping (AFIO) ([#4430](https://github.com/embassy-rs/embassy/pull/4430))
|
||||||
|
|
||||||
## 0.3.0 - 2025-08-12
|
## 0.3.0 - 2025-08-12
|
||||||
|
|
||||||
|
@ -1391,9 +1391,53 @@ fn main() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
g.extend(quote! {
|
let pin_trait_impl = if let Some(afio) = &p.afio {
|
||||||
pin_trait_impl!(#tr, #peri, #pin_name, #af);
|
let values = afio
|
||||||
})
|
.values
|
||||||
|
.iter()
|
||||||
|
.filter(|v| v.pins.contains(&pin.pin))
|
||||||
|
.map(|v| v.value)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if values.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let reg = format_ident!("{}", afio.register.to_lowercase());
|
||||||
|
let setter = format_ident!("set_{}", afio.field.to_lowercase());
|
||||||
|
let type_and_values = if is_bool_field("AFIO", afio.register, afio.field) {
|
||||||
|
let values = values.iter().map(|&v| v > 0);
|
||||||
|
quote!(AfioRemapBool, [#(#values),*])
|
||||||
|
} else {
|
||||||
|
quote!(AfioRemap, [#(#values),*])
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(quote! {
|
||||||
|
pin_trait_afio_impl!(#tr, #peri, #pin_name, {#reg, #setter, #type_and_values});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let peripherals_with_afio = [
|
||||||
|
"CAN",
|
||||||
|
"CEC",
|
||||||
|
"ETH",
|
||||||
|
"I2C",
|
||||||
|
"SPI",
|
||||||
|
"SUBGHZSPI",
|
||||||
|
"USART",
|
||||||
|
"UART",
|
||||||
|
"LPUART",
|
||||||
|
"TIM",
|
||||||
|
];
|
||||||
|
let not_applicable = if peripherals_with_afio.iter().any(|&x| p.name.starts_with(x)) {
|
||||||
|
quote!(, crate::gpio::AfioRemapNotApplicable)
|
||||||
|
} else {
|
||||||
|
quote!()
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(quote!(pin_trait_impl!(#tr, #peri, #pin_name, #af #not_applicable);))
|
||||||
|
};
|
||||||
|
|
||||||
|
g.extend(pin_trait_impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ADC is special
|
// ADC is special
|
||||||
@ -1588,17 +1632,7 @@ fn main() {
|
|||||||
let register = format_ident!("{}", remap_info.register.to_lowercase());
|
let register = format_ident!("{}", remap_info.register.to_lowercase());
|
||||||
let setter = format_ident!("set_{}", remap_info.field.to_lowercase());
|
let setter = format_ident!("set_{}", remap_info.field.to_lowercase());
|
||||||
|
|
||||||
let field_metadata = METADATA
|
let value = if is_bool_field("SYSCFG", &remap_info.register, &remap_info.field) {
|
||||||
.peripherals
|
|
||||||
.iter()
|
|
||||||
.filter(|p| p.name == "SYSCFG")
|
|
||||||
.flat_map(|p| p.registers.as_ref().unwrap().ir.fieldsets.iter())
|
|
||||||
.filter(|f| f.name.eq_ignore_ascii_case(remap_info.register))
|
|
||||||
.flat_map(|f| f.fields.iter())
|
|
||||||
.find(|f| f.name.eq_ignore_ascii_case(remap_info.field))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let value = if field_metadata.bit_size == 1 {
|
|
||||||
let bool_value = format_ident!("{}", remap_info.value > 0);
|
let bool_value = format_ident!("{}", remap_info.value > 0);
|
||||||
quote!(#bool_value)
|
quote!(#bool_value)
|
||||||
} else {
|
} else {
|
||||||
@ -2300,3 +2334,17 @@ fn gcd(a: u32, b: u32) -> u32 {
|
|||||||
}
|
}
|
||||||
gcd(b, a % b)
|
gcd(b, a % b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_bool_field(peripheral: &str, register: &str, field: &str) -> bool {
|
||||||
|
let field_metadata = METADATA
|
||||||
|
.peripherals
|
||||||
|
.iter()
|
||||||
|
.filter(|p| p.name == peripheral)
|
||||||
|
.flat_map(|p| p.registers.as_ref().unwrap().ir.fieldsets.iter())
|
||||||
|
.filter(|f| f.name.eq_ignore_ascii_case(register))
|
||||||
|
.flat_map(|f| f.fields.iter())
|
||||||
|
.find(|f| f.name.eq_ignore_ascii_case(field))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
field_metadata.bit_size == 1
|
||||||
|
}
|
||||||
|
@ -181,10 +181,10 @@ pub enum TryWriteError {
|
|||||||
impl<'d> Can<'d> {
|
impl<'d> Can<'d> {
|
||||||
/// Creates a new Bxcan instance, keeping the peripheral in sleep mode.
|
/// Creates a new Bxcan instance, keeping the peripheral in sleep mode.
|
||||||
/// You must call [Can::enable_non_blocking] to use the peripheral.
|
/// You must call [Can::enable_non_blocking] to use the peripheral.
|
||||||
pub fn new<T: Instance>(
|
pub fn new<T: Instance, #[cfg(afio)] A>(
|
||||||
_peri: Peri<'d, T>,
|
_peri: Peri<'d, T>,
|
||||||
rx: Peri<'d, impl RxPin<T>>,
|
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
|
||||||
tx: Peri<'d, impl TxPin<T>>,
|
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
|
||||||
_irqs: impl interrupt::typelevel::Binding<T::TXInterrupt, TxInterruptHandler<T>>
|
_irqs: impl interrupt::typelevel::Binding<T::TXInterrupt, TxInterruptHandler<T>>
|
||||||
+ interrupt::typelevel::Binding<T::RX0Interrupt, Rx0InterruptHandler<T>>
|
+ interrupt::typelevel::Binding<T::RX0Interrupt, Rx0InterruptHandler<T>>
|
||||||
+ interrupt::typelevel::Binding<T::RX1Interrupt, Rx1InterruptHandler<T>>
|
+ interrupt::typelevel::Binding<T::RX1Interrupt, Rx1InterruptHandler<T>>
|
||||||
@ -194,8 +194,8 @@ impl<'d> Can<'d> {
|
|||||||
let info = T::info();
|
let info = T::info();
|
||||||
let regs = &T::info().regs;
|
let regs = &T::info().regs;
|
||||||
|
|
||||||
rx.set_as_af(rx.af_num(), AfType::input(Pull::None));
|
set_as_af!(rx, AfType::input(Pull::None));
|
||||||
tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
set_as_af!(tx, AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
||||||
|
|
||||||
rcc::enable_and_reset::<T>();
|
rcc::enable_and_reset::<T>();
|
||||||
|
|
||||||
@ -229,8 +229,8 @@ impl<'d> Can<'d> {
|
|||||||
info.sce_interrupt.enable();
|
info.sce_interrupt.enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
rx.set_as_af(rx.af_num(), AfType::input(Pull::None));
|
set_as_af!(rx, AfType::input(Pull::None));
|
||||||
tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
set_as_af!(tx, AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
||||||
|
|
||||||
Registers(T::regs()).leave_init_mode();
|
Registers(T::regs()).leave_init_mode();
|
||||||
|
|
||||||
@ -1218,8 +1218,8 @@ foreach_peripheral!(
|
|||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
|
||||||
pin_trait!(RxPin, Instance);
|
pin_trait!(RxPin, Instance, @A);
|
||||||
pin_trait!(TxPin, Instance);
|
pin_trait!(TxPin, Instance, @A);
|
||||||
|
|
||||||
trait Index {
|
trait Index {
|
||||||
fn index(&self) -> usize;
|
fn index(&self) -> usize;
|
||||||
|
@ -185,8 +185,8 @@ impl<'d> CanConfigurator<'d> {
|
|||||||
+ interrupt::typelevel::Binding<T::IT1Interrupt, IT1InterruptHandler<T>>
|
+ interrupt::typelevel::Binding<T::IT1Interrupt, IT1InterruptHandler<T>>
|
||||||
+ 'd,
|
+ 'd,
|
||||||
) -> CanConfigurator<'d> {
|
) -> CanConfigurator<'d> {
|
||||||
rx.set_as_af(rx.af_num(), AfType::input(Pull::None));
|
set_as_af!(rx, AfType::input(Pull::None));
|
||||||
tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
set_as_af!(tx, AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
||||||
|
|
||||||
rcc::enable_and_reset::<T>();
|
rcc::enable_and_reset::<T>();
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ macro_rules! config_pins {
|
|||||||
($($pin:ident),*) => {
|
($($pin:ident),*) => {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
$(
|
$(
|
||||||
$pin.set_as_af($pin.af_num(), AfType::input(Pull::None));
|
set_as_af!($pin, AfType::input(Pull::None));
|
||||||
)*
|
)*
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
@ -78,7 +78,7 @@ impl<'d, T: Instance> DsiHost<'d, T> {
|
|||||||
rcc::enable_and_reset::<T>();
|
rcc::enable_and_reset::<T>();
|
||||||
|
|
||||||
// Set Tearing Enable pin according to CubeMx example
|
// Set Tearing Enable pin according to CubeMx example
|
||||||
te.set_as_af(te.af_num(), AfType::output(OutputType::PushPull, Speed::Low));
|
set_as_af!(te, AfType::output(OutputType::PushPull, Speed::Low));
|
||||||
/*
|
/*
|
||||||
T::regs().wcr().modify(|w| {
|
T::regs().wcr().modify(|w| {
|
||||||
w.set_dsien(true);
|
w.set_dsien(true);
|
||||||
|
@ -209,19 +209,19 @@ impl SealedInstance for crate::peripherals::ETH {
|
|||||||
}
|
}
|
||||||
impl Instance for crate::peripherals::ETH {}
|
impl Instance for crate::peripherals::ETH {}
|
||||||
|
|
||||||
pin_trait!(RXClkPin, Instance);
|
pin_trait!(RXClkPin, Instance, @A);
|
||||||
pin_trait!(TXClkPin, Instance);
|
pin_trait!(TXClkPin, Instance, @A);
|
||||||
pin_trait!(RefClkPin, Instance);
|
pin_trait!(RefClkPin, Instance, @A);
|
||||||
pin_trait!(MDIOPin, Instance);
|
pin_trait!(MDIOPin, Instance, @A);
|
||||||
pin_trait!(MDCPin, Instance);
|
pin_trait!(MDCPin, Instance, @A);
|
||||||
pin_trait!(RXDVPin, Instance);
|
pin_trait!(RXDVPin, Instance, @A);
|
||||||
pin_trait!(CRSPin, Instance);
|
pin_trait!(CRSPin, Instance, @A);
|
||||||
pin_trait!(RXD0Pin, Instance);
|
pin_trait!(RXD0Pin, Instance, @A);
|
||||||
pin_trait!(RXD1Pin, Instance);
|
pin_trait!(RXD1Pin, Instance, @A);
|
||||||
pin_trait!(RXD2Pin, Instance);
|
pin_trait!(RXD2Pin, Instance, @A);
|
||||||
pin_trait!(RXD3Pin, Instance);
|
pin_trait!(RXD3Pin, Instance, @A);
|
||||||
pin_trait!(TXD0Pin, Instance);
|
pin_trait!(TXD0Pin, Instance, @A);
|
||||||
pin_trait!(TXD1Pin, Instance);
|
pin_trait!(TXD1Pin, Instance, @A);
|
||||||
pin_trait!(TXD2Pin, Instance);
|
pin_trait!(TXD2Pin, Instance, @A);
|
||||||
pin_trait!(TXD3Pin, Instance);
|
pin_trait!(TXD3Pin, Instance, @A);
|
||||||
pin_trait!(TXEnPin, Instance);
|
pin_trait!(TXEnPin, Instance, @A);
|
||||||
|
@ -69,7 +69,7 @@ macro_rules! config_in_pins {
|
|||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
$(
|
$(
|
||||||
// TODO properly create a set_as_input function
|
// TODO properly create a set_as_input function
|
||||||
$pin.set_as_af($pin.af_num(), AfType::input(Pull::None));
|
set_as_af!($pin, AfType::input(Pull::None));
|
||||||
)*
|
)*
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -80,7 +80,7 @@ macro_rules! config_af_pins {
|
|||||||
($($pin:ident),*) => {
|
($($pin:ident),*) => {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
$(
|
$(
|
||||||
$pin.set_as_af($pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
set_as_af!($pin, AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
||||||
)*
|
)*
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@ -91,7 +91,7 @@ macro_rules! config_pins {
|
|||||||
($($pin:ident),*) => {
|
($($pin:ident),*) => {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
$(
|
$(
|
||||||
$pin.set_as_af($pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
set_as_af!($pin, AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
||||||
)*
|
)*
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@ -99,19 +99,19 @@ macro_rules! config_pins {
|
|||||||
|
|
||||||
impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
|
impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
|
||||||
/// safety: the returned instance is not leak-safe
|
/// safety: the returned instance is not leak-safe
|
||||||
pub fn new<const TX: usize, const RX: usize>(
|
pub fn new<const TX: usize, const RX: usize, #[cfg(afio)] A>(
|
||||||
queue: &'d mut PacketQueue<TX, RX>,
|
queue: &'d mut PacketQueue<TX, RX>,
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
|
irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
|
||||||
ref_clk: Peri<'d, impl RefClkPin<T>>,
|
ref_clk: Peri<'d, if_afio!(impl RefClkPin<T, A>)>,
|
||||||
mdio: Peri<'d, impl MDIOPin<T>>,
|
mdio: Peri<'d, if_afio!(impl MDIOPin<T, A>)>,
|
||||||
mdc: Peri<'d, impl MDCPin<T>>,
|
mdc: Peri<'d, if_afio!(impl MDCPin<T, A>)>,
|
||||||
crs: Peri<'d, impl CRSPin<T>>,
|
crs: Peri<'d, if_afio!(impl CRSPin<T, A>)>,
|
||||||
rx_d0: Peri<'d, impl RXD0Pin<T>>,
|
rx_d0: Peri<'d, if_afio!(impl RXD0Pin<T, A>)>,
|
||||||
rx_d1: Peri<'d, impl RXD1Pin<T>>,
|
rx_d1: Peri<'d, if_afio!(impl RXD1Pin<T, A>)>,
|
||||||
tx_d0: Peri<'d, impl TXD0Pin<T>>,
|
tx_d0: Peri<'d, if_afio!(impl TXD0Pin<T, A>)>,
|
||||||
tx_d1: Peri<'d, impl TXD1Pin<T>>,
|
tx_d1: Peri<'d, if_afio!(impl TXD1Pin<T, A>)>,
|
||||||
tx_en: Peri<'d, impl TXEnPin<T>>,
|
tx_en: Peri<'d, if_afio!(impl TXEnPin<T, A>)>,
|
||||||
phy: P,
|
phy: P,
|
||||||
mac_addr: [u8; 6],
|
mac_addr: [u8; 6],
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@ -289,24 +289,24 @@ impl<'d, T: Instance, P: Phy> Ethernet<'d, T, P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new MII ethernet driver using 14 pins.
|
/// Create a new MII ethernet driver using 14 pins.
|
||||||
pub fn new_mii<const TX: usize, const RX: usize>(
|
pub fn new_mii<const TX: usize, const RX: usize, #[cfg(afio)] A>(
|
||||||
queue: &'d mut PacketQueue<TX, RX>,
|
queue: &'d mut PacketQueue<TX, RX>,
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
|
irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
|
||||||
rx_clk: Peri<'d, impl RXClkPin<T>>,
|
rx_clk: Peri<'d, if_afio!(impl RXClkPin<T, A>)>,
|
||||||
tx_clk: Peri<'d, impl TXClkPin<T>>,
|
tx_clk: Peri<'d, if_afio!(impl TXClkPin<T, A>)>,
|
||||||
mdio: Peri<'d, impl MDIOPin<T>>,
|
mdio: Peri<'d, if_afio!(impl MDIOPin<T, A>)>,
|
||||||
mdc: Peri<'d, impl MDCPin<T>>,
|
mdc: Peri<'d, if_afio!(impl MDCPin<T, A>)>,
|
||||||
rxdv: Peri<'d, impl RXDVPin<T>>,
|
rxdv: Peri<'d, if_afio!(impl RXDVPin<T, A>)>,
|
||||||
rx_d0: Peri<'d, impl RXD0Pin<T>>,
|
rx_d0: Peri<'d, if_afio!(impl RXD0Pin<T, A>)>,
|
||||||
rx_d1: Peri<'d, impl RXD1Pin<T>>,
|
rx_d1: Peri<'d, if_afio!(impl RXD1Pin<T, A>)>,
|
||||||
rx_d2: Peri<'d, impl RXD2Pin<T>>,
|
rx_d2: Peri<'d, if_afio!(impl RXD2Pin<T, A>)>,
|
||||||
rx_d3: Peri<'d, impl RXD3Pin<T>>,
|
rx_d3: Peri<'d, if_afio!(impl RXD3Pin<T, A>)>,
|
||||||
tx_d0: Peri<'d, impl TXD0Pin<T>>,
|
tx_d0: Peri<'d, if_afio!(impl TXD0Pin<T, A>)>,
|
||||||
tx_d1: Peri<'d, impl TXD1Pin<T>>,
|
tx_d1: Peri<'d, if_afio!(impl TXD1Pin<T, A>)>,
|
||||||
tx_d2: Peri<'d, impl TXD2Pin<T>>,
|
tx_d2: Peri<'d, if_afio!(impl TXD2Pin<T, A>)>,
|
||||||
tx_d3: Peri<'d, impl TXD3Pin<T>>,
|
tx_d3: Peri<'d, if_afio!(impl TXD3Pin<T, A>)>,
|
||||||
tx_en: Peri<'d, impl TXEnPin<T>>,
|
tx_en: Peri<'d, if_afio!(impl TXEnPin<T, A>)>,
|
||||||
phy: P,
|
phy: P,
|
||||||
mac_addr: [u8; 6],
|
mac_addr: [u8; 6],
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -57,7 +57,7 @@ macro_rules! config_pins {
|
|||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
$(
|
$(
|
||||||
// TODO: shouldn't some pins be configured as inputs?
|
// TODO: shouldn't some pins be configured as inputs?
|
||||||
$pin.set_as_af($pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
set_as_af!($pin, AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
||||||
)*
|
)*
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
@ -75,7 +75,7 @@ where
|
|||||||
macro_rules! config_pins {
|
macro_rules! config_pins {
|
||||||
($($pin:ident),*) => {
|
($($pin:ident),*) => {
|
||||||
$(
|
$(
|
||||||
$pin.set_as_af($pin.af_num(), AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up));
|
set_as_af!($pin, AfType::output_pull(OutputType::PushPull, Speed::VeryHigh, Pull::Up));
|
||||||
)*
|
)*
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -150,9 +150,13 @@ impl<'d> Flex<'d> {
|
|||||||
/// This puts the pin into the AF mode, with the requested number and AF type. This is
|
/// This puts the pin into the AF mode, with the requested number and AF type. This is
|
||||||
/// completely unchecked, it can attach the pin to literally any peripheral, so use with care.
|
/// completely unchecked, it can attach the pin to literally any peripheral, so use with care.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_as_af_unchecked(&mut self, af_num: u8, af_type: AfType) {
|
pub fn set_as_af_unchecked(&mut self, #[cfg(not(afio))] af_num: u8, af_type: AfType) {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
self.pin.set_as_af(af_num, af_type);
|
self.pin.set_as_af(
|
||||||
|
#[cfg(not(afio))]
|
||||||
|
af_num,
|
||||||
|
af_type,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,7 +592,7 @@ impl AfType {
|
|||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
#[cfg(gpio_v1)]
|
#[cfg(gpio_v1)]
|
||||||
fn set_as_af(pin_port: u8, _af_num: u8, af_type: AfType) {
|
fn set_as_af(pin_port: u8, af_type: AfType) {
|
||||||
let pin = unsafe { AnyPin::steal(pin_port) };
|
let pin = unsafe { AnyPin::steal(pin_port) };
|
||||||
let r = pin.block();
|
let r = pin.block();
|
||||||
let n = pin._pin() as usize;
|
let n = pin._pin() as usize;
|
||||||
@ -710,6 +714,18 @@ fn get_pull(pin_port: u8) -> Pull {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(afio)]
|
||||||
|
/// Holds the AFIO remap value for a peripheral's pin
|
||||||
|
pub struct AfioRemap<const V: u8>;
|
||||||
|
|
||||||
|
#[cfg(afio)]
|
||||||
|
/// Holds the AFIO remap value for a peripheral's pin
|
||||||
|
pub struct AfioRemapBool<const V: bool>;
|
||||||
|
|
||||||
|
#[cfg(afio)]
|
||||||
|
/// Placeholder for a peripheral's pin which cannot be remapped via AFIO.
|
||||||
|
pub struct AfioRemapNotApplicable;
|
||||||
|
|
||||||
pub(crate) trait SealedPin {
|
pub(crate) trait SealedPin {
|
||||||
fn pin_port(&self) -> u8;
|
fn pin_port(&self) -> u8;
|
||||||
|
|
||||||
@ -743,8 +759,13 @@ pub(crate) trait SealedPin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_as_af(&self, af_num: u8, af_type: AfType) {
|
fn set_as_af(&self, #[cfg(not(afio))] af_num: u8, af_type: AfType) {
|
||||||
set_as_af(self.pin_port(), af_num, af_type)
|
set_as_af(
|
||||||
|
self.pin_port(),
|
||||||
|
#[cfg(not(afio))]
|
||||||
|
af_num,
|
||||||
|
af_type,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -79,10 +79,7 @@ macro_rules! advanced_channel_impl {
|
|||||||
pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T>>) -> Self {
|
pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T>>) -> Self {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
pin.set_low();
|
pin.set_low();
|
||||||
pin.set_as_af(
|
set_as_af!(pin, AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
||||||
pin.af_num(),
|
|
||||||
AfType::output(OutputType::PushPull, Speed::VeryHigh),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
PwmPin {
|
PwmPin {
|
||||||
_pin: pin.into(),
|
_pin: pin.into(),
|
||||||
@ -96,10 +93,7 @@ macro_rules! advanced_channel_impl {
|
|||||||
pub fn $new_chx(pin: Peri<'d, impl $complementary_pin_trait<T>>) -> Self {
|
pub fn $new_chx(pin: Peri<'d, impl $complementary_pin_trait<T>>) -> Self {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
pin.set_low();
|
pin.set_low();
|
||||||
pin.set_as_af(
|
set_as_af!(pin, AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
||||||
pin.af_num(),
|
|
||||||
AfType::output(OutputType::PushPull, Speed::VeryHigh),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
ComplementaryPwmPin {
|
ComplementaryPwmPin {
|
||||||
_pin: pin.into(),
|
_pin: pin.into(),
|
||||||
|
@ -149,10 +149,10 @@ pub struct I2c<'d, M: Mode, IM: MasterMode> {
|
|||||||
|
|
||||||
impl<'d> I2c<'d, Async, Master> {
|
impl<'d> I2c<'d, Async, Master> {
|
||||||
/// Create a new I2C driver.
|
/// Create a new I2C driver.
|
||||||
pub fn new<T: Instance>(
|
pub fn new<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
scl: Peri<'d, impl SclPin<T>>,
|
scl: Peri<'d, if_afio!(impl SclPin<T, A>)>,
|
||||||
sda: Peri<'d, impl SdaPin<T>>,
|
sda: Peri<'d, if_afio!(impl SdaPin<T, A>)>,
|
||||||
_irq: impl interrupt::typelevel::Binding<T::EventInterrupt, EventInterruptHandler<T>>
|
_irq: impl interrupt::typelevel::Binding<T::EventInterrupt, EventInterruptHandler<T>>
|
||||||
+ interrupt::typelevel::Binding<T::ErrorInterrupt, ErrorInterruptHandler<T>>
|
+ interrupt::typelevel::Binding<T::ErrorInterrupt, ErrorInterruptHandler<T>>
|
||||||
+ 'd,
|
+ 'd,
|
||||||
@ -173,10 +173,10 @@ impl<'d> I2c<'d, Async, Master> {
|
|||||||
|
|
||||||
impl<'d> I2c<'d, Blocking, Master> {
|
impl<'d> I2c<'d, Blocking, Master> {
|
||||||
/// Create a new blocking I2C driver.
|
/// Create a new blocking I2C driver.
|
||||||
pub fn new_blocking<T: Instance>(
|
pub fn new_blocking<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
scl: Peri<'d, impl SclPin<T>>,
|
scl: Peri<'d, if_afio!(impl SclPin<T, A>)>,
|
||||||
sda: Peri<'d, impl SdaPin<T>>,
|
sda: Peri<'d, if_afio!(impl SdaPin<T, A>)>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
@ -296,8 +296,8 @@ peri_trait!(
|
|||||||
irqs: [EventInterrupt, ErrorInterrupt],
|
irqs: [EventInterrupt, ErrorInterrupt],
|
||||||
);
|
);
|
||||||
|
|
||||||
pin_trait!(SclPin, Instance);
|
pin_trait!(SclPin, Instance, @A);
|
||||||
pin_trait!(SdaPin, Instance);
|
pin_trait!(SdaPin, Instance, @A);
|
||||||
dma_trait!(RxDma, Instance);
|
dma_trait!(RxDma, Instance);
|
||||||
dma_trait!(TxDma, Instance);
|
dma_trait!(TxDma, Instance);
|
||||||
|
|
||||||
|
@ -237,12 +237,12 @@ pub struct I2S<'d, W: Word> {
|
|||||||
|
|
||||||
impl<'d, W: Word> I2S<'d, W> {
|
impl<'d, W: Word> I2S<'d, W> {
|
||||||
/// Create a transmitter driver.
|
/// Create a transmitter driver.
|
||||||
pub fn new_txonly<T: Instance>(
|
pub fn new_txonly<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
sd: Peri<'d, impl MosiPin<T>>,
|
sd: Peri<'d, if_afio!(impl MosiPin<T, A>)>,
|
||||||
ws: Peri<'d, impl WsPin<T>>,
|
ws: Peri<'d, if_afio!(impl WsPin<T, A>)>,
|
||||||
ck: Peri<'d, impl CkPin<T>>,
|
ck: Peri<'d, if_afio!(impl CkPin<T, A>)>,
|
||||||
mck: Peri<'d, impl MckPin<T>>,
|
mck: Peri<'d, if_afio!(impl MckPin<T, A>)>,
|
||||||
txdma: Peri<'d, impl TxDma<T>>,
|
txdma: Peri<'d, impl TxDma<T>>,
|
||||||
txdma_buf: &'d mut [W],
|
txdma_buf: &'d mut [W],
|
||||||
config: Config,
|
config: Config,
|
||||||
@ -262,11 +262,11 @@ impl<'d, W: Word> I2S<'d, W> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a transmitter driver without a master clock pin.
|
/// Create a transmitter driver without a master clock pin.
|
||||||
pub fn new_txonly_nomck<T: Instance>(
|
pub fn new_txonly_nomck<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
sd: Peri<'d, impl MosiPin<T>>,
|
sd: Peri<'d, if_afio!(impl MosiPin<T, A>)>,
|
||||||
ws: Peri<'d, impl WsPin<T>>,
|
ws: Peri<'d, if_afio!(impl WsPin<T, A>)>,
|
||||||
ck: Peri<'d, impl CkPin<T>>,
|
ck: Peri<'d, if_afio!(impl CkPin<T, A>)>,
|
||||||
txdma: Peri<'d, impl TxDma<T>>,
|
txdma: Peri<'d, impl TxDma<T>>,
|
||||||
txdma_buf: &'d mut [W],
|
txdma_buf: &'d mut [W],
|
||||||
config: Config,
|
config: Config,
|
||||||
@ -286,12 +286,12 @@ impl<'d, W: Word> I2S<'d, W> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a receiver driver.
|
/// Create a receiver driver.
|
||||||
pub fn new_rxonly<T: Instance>(
|
pub fn new_rxonly<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
sd: Peri<'d, impl MisoPin<T>>,
|
sd: Peri<'d, if_afio!(impl MisoPin<T, A>)>,
|
||||||
ws: Peri<'d, impl WsPin<T>>,
|
ws: Peri<'d, if_afio!(impl WsPin<T, A>)>,
|
||||||
ck: Peri<'d, impl CkPin<T>>,
|
ck: Peri<'d, if_afio!(impl CkPin<T, A>)>,
|
||||||
mck: Peri<'d, impl MckPin<T>>,
|
mck: Peri<'d, if_afio!(impl MckPin<T, A>)>,
|
||||||
rxdma: Peri<'d, impl RxDma<T>>,
|
rxdma: Peri<'d, impl RxDma<T>>,
|
||||||
rxdma_buf: &'d mut [W],
|
rxdma_buf: &'d mut [W],
|
||||||
config: Config,
|
config: Config,
|
||||||
@ -313,13 +313,13 @@ impl<'d, W: Word> I2S<'d, W> {
|
|||||||
#[cfg(any(spi_v4, spi_v5))]
|
#[cfg(any(spi_v4, spi_v5))]
|
||||||
|
|
||||||
/// Create a full duplex driver.
|
/// Create a full duplex driver.
|
||||||
pub fn new_full_duplex<T: Instance>(
|
pub fn new_full_duplex<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
txsd: Peri<'d, impl MosiPin<T>>,
|
txsd: Peri<'d, if_afio!(impl MosiPin<T, A>)>,
|
||||||
rxsd: Peri<'d, impl MisoPin<T>>,
|
rxsd: Peri<'d, if_afio!(impl MisoPin<T, A>)>,
|
||||||
ws: Peri<'d, impl WsPin<T>>,
|
ws: Peri<'d, if_afio!(impl WsPin<T, A>)>,
|
||||||
ck: Peri<'d, impl CkPin<T>>,
|
ck: Peri<'d, if_afio!(impl CkPin<T, A>)>,
|
||||||
mck: Peri<'d, impl MckPin<T>>,
|
mck: Peri<'d, if_afio!(impl MckPin<T, A>)>,
|
||||||
txdma: Peri<'d, impl TxDma<T>>,
|
txdma: Peri<'d, impl TxDma<T>>,
|
||||||
txdma_buf: &'d mut [W],
|
txdma_buf: &'d mut [W],
|
||||||
rxdma: Peri<'d, impl RxDma<T>>,
|
rxdma: Peri<'d, impl RxDma<T>>,
|
||||||
@ -459,20 +459,20 @@ impl<'d, W: Word> I2S<'d, W> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_inner<T: Instance>(
|
fn new_inner<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
txsd: Option<Peri<'d, AnyPin>>,
|
txsd: Option<Peri<'d, AnyPin>>,
|
||||||
rxsd: Option<Peri<'d, AnyPin>>,
|
rxsd: Option<Peri<'d, AnyPin>>,
|
||||||
ws: Peri<'d, impl WsPin<T>>,
|
ws: Peri<'d, if_afio!(impl WsPin<T, A>)>,
|
||||||
ck: Peri<'d, impl CkPin<T>>,
|
ck: Peri<'d, if_afio!(impl CkPin<T, A>)>,
|
||||||
mck: Option<Peri<'d, AnyPin>>,
|
mck: Option<Peri<'d, AnyPin>>,
|
||||||
txdma: Option<(ChannelAndRequest<'d>, &'d mut [W])>,
|
txdma: Option<(ChannelAndRequest<'d>, &'d mut [W])>,
|
||||||
rxdma: Option<(ChannelAndRequest<'d>, &'d mut [W])>,
|
rxdma: Option<(ChannelAndRequest<'d>, &'d mut [W])>,
|
||||||
config: Config,
|
config: Config,
|
||||||
function: Function,
|
function: Function,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
ws.set_as_af(ws.af_num(), AfType::output(OutputType::PushPull, config.gpio_speed));
|
set_as_af!(ws, AfType::output(OutputType::PushPull, config.gpio_speed));
|
||||||
ck.set_as_af(ck.af_num(), AfType::output(OutputType::PushPull, config.gpio_speed));
|
set_as_af!(ck, AfType::output(OutputType::PushPull, config.gpio_speed));
|
||||||
|
|
||||||
let spi = Spi::new_internal(peri, None, None, {
|
let spi = Spi::new_internal(peri, None, None, {
|
||||||
let mut spi_config = SpiConfig::default();
|
let mut spi_config = SpiConfig::default();
|
||||||
|
@ -50,10 +50,7 @@ macro_rules! channel_impl {
|
|||||||
pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T>>) -> Self {
|
pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T>>) -> Self {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
pin.set_low();
|
pin.set_low();
|
||||||
pin.set_as_af(
|
set_as_af!(pin, AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
||||||
pin.af_num(),
|
|
||||||
AfType::output(OutputType::PushPull, Speed::VeryHigh),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
PwmPin {
|
PwmPin {
|
||||||
_pin: pin.into(),
|
_pin: pin.into(),
|
||||||
@ -64,12 +61,12 @@ macro_rules! channel_impl {
|
|||||||
pub fn $new_chx_with_config(pin: Peri<'d, impl $pin_trait<T>>, pin_config: PwmPinConfig) -> Self {
|
pub fn $new_chx_with_config(pin: Peri<'d, impl $pin_trait<T>>, pin_config: PwmPinConfig) -> Self {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
pin.set_low();
|
pin.set_low();
|
||||||
pin.set_as_af(
|
#[cfg(gpio_v1)]
|
||||||
pin.af_num(),
|
set_as_af!(pin, AfType::output(pin_config.output_type, pin_config.speed));
|
||||||
#[cfg(gpio_v1)]
|
#[cfg(gpio_v2)]
|
||||||
AfType::output(pin_config.output_type, pin_config.speed),
|
set_as_af!(
|
||||||
#[cfg(gpio_v2)]
|
pin,
|
||||||
AfType::output_pull(pin_config.output_type, pin_config.speed, pin_config.pull),
|
AfType::output_pull(pin_config.output_type, pin_config.speed, pin_config.pull)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
PwmPin {
|
PwmPin {
|
||||||
|
@ -41,17 +41,30 @@ macro_rules! peri_trait_impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! pin_trait {
|
macro_rules! pin_trait {
|
||||||
($signal:ident, $instance:path $(, $mode:path)?) => {
|
($signal:ident, $instance:path $(, $mode:path)? $(, @$afio:ident)?) => {
|
||||||
#[doc = concat!(stringify!($signal), " pin trait")]
|
#[doc = concat!(stringify!($signal), " pin trait")]
|
||||||
pub trait $signal<T: $instance $(, M: $mode)?>: crate::gpio::Pin {
|
pub trait $signal<T: $instance $(, M: $mode)? $(, #[cfg(afio)] $afio)?>: crate::gpio::Pin {
|
||||||
|
#[cfg(not(afio))]
|
||||||
#[doc = concat!("Get the AF number needed to use this pin as ", stringify!($signal))]
|
#[doc = concat!("Get the AF number needed to use this pin as ", stringify!($signal))]
|
||||||
fn af_num(&self) -> u8;
|
fn af_num(&self) -> u8;
|
||||||
|
|
||||||
|
#[cfg(afio)]
|
||||||
|
#[doc = concat!("Configures AFIO_MAPR to use this pin as ", stringify!($signal))]
|
||||||
|
fn afio_remap(&self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! pin_trait_impl {
|
macro_rules! pin_trait_impl {
|
||||||
(crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, $pin:ident, $af:expr) => {
|
(crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, $pin:ident, $af:expr $(, $afio:path)?) => {
|
||||||
|
#[cfg(afio)]
|
||||||
|
impl crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)? $(, $afio)?> for crate::peripherals::$pin {
|
||||||
|
fn afio_remap(&self) {
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(afio))]
|
||||||
impl crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for crate::peripherals::$pin {
|
impl crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for crate::peripherals::$pin {
|
||||||
fn af_num(&self) -> u8 {
|
fn af_num(&self) -> u8 {
|
||||||
$af
|
$af
|
||||||
@ -60,6 +73,39 @@ macro_rules! pin_trait_impl {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(afio)]
|
||||||
|
macro_rules! pin_trait_afio_impl {
|
||||||
|
(@set mapr, $setter:ident, $val:expr) => {
|
||||||
|
crate::pac::AFIO.mapr().modify(|w| {
|
||||||
|
w.set_swj_cfg(crate::pac::afio::vals::SwjCfg::NO_OP);
|
||||||
|
w.$setter($val);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
(@set mapr2, $setter:ident, $val:expr) => {
|
||||||
|
crate::pac::AFIO.mapr2().modify(|w| {
|
||||||
|
w.$setter($val);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
(crate::$mod:ident::$trait:ident<$mode:ident>, $instance:ident, $pin:ident, {$reg:ident, $setter:ident, $type:ident, [$($val:expr),+]}) => {
|
||||||
|
$(
|
||||||
|
impl crate::$mod::$trait<crate::peripherals::$instance, crate::$mod::$mode, crate::gpio::$type<$val>> for crate::peripherals::$pin {
|
||||||
|
fn afio_remap(&self) {
|
||||||
|
pin_trait_afio_impl!(@set $reg, $setter, $val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
};
|
||||||
|
(crate::$mod:ident::$trait:ident, $instance:ident, $pin:ident, {$reg:ident, $setter:ident, $type:ident, [$($val:expr),+]}) => {
|
||||||
|
$(
|
||||||
|
impl crate::$mod::$trait<crate::peripherals::$instance, crate::gpio::$type<$val>> for crate::peripherals::$pin {
|
||||||
|
fn afio_remap(&self) {
|
||||||
|
pin_trait_afio_impl!(@set $reg, $setter, $val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(unused_macros)]
|
#[allow(unused_macros)]
|
||||||
macro_rules! sel_trait_impl {
|
macro_rules! sel_trait_impl {
|
||||||
(crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, $pin:ident, $sel:expr) => {
|
(crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, $pin:ident, $sel:expr) => {
|
||||||
@ -134,7 +180,73 @@ macro_rules! new_dma {
|
|||||||
macro_rules! new_pin {
|
macro_rules! new_pin {
|
||||||
($name:ident, $af_type:expr) => {{
|
($name:ident, $af_type:expr) => {{
|
||||||
let pin = $name;
|
let pin = $name;
|
||||||
pin.set_as_af(pin.af_num(), $af_type);
|
#[cfg(afio)]
|
||||||
|
pin.afio_remap();
|
||||||
|
pin.set_as_af(
|
||||||
|
#[cfg(not(afio))]
|
||||||
|
pin.af_num(),
|
||||||
|
$af_type,
|
||||||
|
);
|
||||||
Some(pin.into())
|
Some(pin.into())
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Macro to configure a pin for alternate function use.
|
||||||
|
/// For AFIO chips (STM32F1), it calls afio_remap().
|
||||||
|
/// For non-AFIO chips, it calls set_as_af() with the pin's af_num().
|
||||||
|
macro_rules! set_as_af {
|
||||||
|
($pin:expr, $af_type:expr) => {
|
||||||
|
#[cfg(afio)]
|
||||||
|
{
|
||||||
|
$pin.set_as_af($af_type);
|
||||||
|
$pin.afio_remap();
|
||||||
|
}
|
||||||
|
#[cfg(not(afio))]
|
||||||
|
{
|
||||||
|
$pin.set_as_af($pin.af_num(), $af_type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(afio)]
|
||||||
|
macro_rules! if_afio {
|
||||||
|
($($t:tt)*) => {
|
||||||
|
$($t)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(not(afio))]
|
||||||
|
macro_rules! if_afio {
|
||||||
|
(($a:ty, A)) => {
|
||||||
|
($a,)
|
||||||
|
};
|
||||||
|
(($a:ty, $b:ty, A)) => {
|
||||||
|
($a,$b)
|
||||||
|
};
|
||||||
|
(($a:ty, $b:ty, $c:ty, A)) => {
|
||||||
|
($a,$b, $c)
|
||||||
|
};
|
||||||
|
($type:ident<$lt:lifetime, $a:ty, $b:ty, A>) => {
|
||||||
|
$type<$lt, $a, $b>
|
||||||
|
};
|
||||||
|
($type:ident<$lt:lifetime, $a:ty, $b:ty, $c:ty, A>) => {
|
||||||
|
$type<$lt, $a, $b, $c>
|
||||||
|
};
|
||||||
|
($type:ident<$a:ty, A>) => {
|
||||||
|
$type<$a>
|
||||||
|
};
|
||||||
|
($type:ident<$a:ty, $b:ty, A>) => {
|
||||||
|
$type<$a, $b>
|
||||||
|
};
|
||||||
|
($type:ident<$a:ty, $b:ty, $c:ty, A>) => {
|
||||||
|
$type<$a, $b, $c>
|
||||||
|
};
|
||||||
|
(impl $trait:ident<$a:ty, A>) => {
|
||||||
|
impl $trait<$a>
|
||||||
|
};
|
||||||
|
(impl $trait:ident<$a:ty, $b:ty, A>) => {
|
||||||
|
impl $trait<$a, $b>
|
||||||
|
};
|
||||||
|
(impl $trait:ident<$a:ty, $b:ty, $c:ty, A>) => {
|
||||||
|
impl $trait<$a, $b, $c>
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -94,7 +94,7 @@ impl<'d, T: McoInstance> Mco<'d, T> {
|
|||||||
pub fn new(_peri: Peri<'d, T>, pin: Peri<'d, impl McoPin<T>>, source: T::Source, prescaler: McoPrescaler) -> Self {
|
pub fn new(_peri: Peri<'d, T>, pin: Peri<'d, impl McoPin<T>>, source: T::Source, prescaler: McoPrescaler) -> Self {
|
||||||
critical_section::with(|_| unsafe {
|
critical_section::with(|_| unsafe {
|
||||||
T::_apply_clock_settings(source, prescaler);
|
T::_apply_clock_settings(source, prescaler);
|
||||||
pin.set_as_af(pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
set_as_af!(pin, AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
||||||
});
|
});
|
||||||
|
|
||||||
Self { phantom: PhantomData }
|
Self { phantom: PhantomData }
|
||||||
|
@ -558,7 +558,7 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
|
|||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let (_sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx);
|
let (_sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx);
|
||||||
mclk.set_as_af(mclk.af_num(), ck_af_type);
|
set_as_af!(mclk, ck_af_type);
|
||||||
|
|
||||||
Self::new_asynchronous(peri, sck, sd, fs, dma, dma_buf, config)
|
Self::new_asynchronous(peri, sck, sd, fs, dma, dma_buf, config)
|
||||||
}
|
}
|
||||||
@ -578,9 +578,9 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
|
|||||||
let peri = peri.peri;
|
let peri = peri.peri;
|
||||||
|
|
||||||
let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx);
|
let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx);
|
||||||
sd.set_as_af(sd.af_num(), sd_af_type);
|
set_as_af!(sd, sd_af_type);
|
||||||
sck.set_as_af(sck.af_num(), ck_af_type);
|
set_as_af!(sck, ck_af_type);
|
||||||
fs.set_as_af(fs.af_num(), ck_af_type);
|
set_as_af!(fs, ck_af_type);
|
||||||
|
|
||||||
let sub_block = S::WHICH;
|
let sub_block = S::WHICH;
|
||||||
let request = dma.request();
|
let request = dma.request();
|
||||||
@ -612,7 +612,7 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
|
|||||||
let peri = peri.peri;
|
let peri = peri.peri;
|
||||||
|
|
||||||
let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx);
|
let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx);
|
||||||
sd.set_as_af(sd.af_num(), sd_af_type);
|
set_as_af!(sd, sd_af_type);
|
||||||
|
|
||||||
let sub_block = S::WHICH;
|
let sub_block = S::WHICH;
|
||||||
let request = dma.request();
|
let request = dma.request();
|
||||||
|
@ -428,9 +428,9 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
|
|||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
clk.set_as_af(clk.af_num(), CLK_AF);
|
set_as_af!(clk, CLK_AF);
|
||||||
cmd.set_as_af(cmd.af_num(), CMD_AF);
|
set_as_af!(cmd, CMD_AF);
|
||||||
d0.set_as_af(d0.af_num(), DATA_AF);
|
set_as_af!(d0, DATA_AF);
|
||||||
});
|
});
|
||||||
|
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
@ -464,12 +464,12 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
|
|||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
clk.set_as_af(clk.af_num(), CLK_AF);
|
set_as_af!(clk, CLK_AF);
|
||||||
cmd.set_as_af(cmd.af_num(), CMD_AF);
|
set_as_af!(cmd, CMD_AF);
|
||||||
d0.set_as_af(d0.af_num(), DATA_AF);
|
set_as_af!(d0, DATA_AF);
|
||||||
d1.set_as_af(d1.af_num(), DATA_AF);
|
set_as_af!(d1, DATA_AF);
|
||||||
d2.set_as_af(d2.af_num(), DATA_AF);
|
set_as_af!(d2, DATA_AF);
|
||||||
d3.set_as_af(d3.af_num(), DATA_AF);
|
set_as_af!(d3, DATA_AF);
|
||||||
});
|
});
|
||||||
|
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
@ -510,16 +510,16 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
|
|||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
clk.set_as_af(clk.af_num(), CLK_AF);
|
set_as_af!(clk, CLK_AF);
|
||||||
cmd.set_as_af(cmd.af_num(), CMD_AF);
|
set_as_af!(cmd, CMD_AF);
|
||||||
d0.set_as_af(d0.af_num(), DATA_AF);
|
set_as_af!(d0, DATA_AF);
|
||||||
d1.set_as_af(d1.af_num(), DATA_AF);
|
set_as_af!(d1, DATA_AF);
|
||||||
d2.set_as_af(d2.af_num(), DATA_AF);
|
set_as_af!(d2, DATA_AF);
|
||||||
d3.set_as_af(d3.af_num(), DATA_AF);
|
set_as_af!(d3, DATA_AF);
|
||||||
d4.set_as_af(d4.af_num(), DATA_AF);
|
set_as_af!(d4, DATA_AF);
|
||||||
d5.set_as_af(d5.af_num(), DATA_AF);
|
set_as_af!(d5, DATA_AF);
|
||||||
d6.set_as_af(d6.af_num(), DATA_AF);
|
set_as_af!(d6, DATA_AF);
|
||||||
d7.set_as_af(d7.af_num(), DATA_AF);
|
set_as_af!(d7, DATA_AF);
|
||||||
});
|
});
|
||||||
|
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
@ -552,9 +552,9 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
|
|||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
clk.set_as_af(clk.af_num(), CLK_AF);
|
set_as_af!(clk, CLK_AF);
|
||||||
cmd.set_as_af(cmd.af_num(), CMD_AF);
|
set_as_af!(cmd, CMD_AF);
|
||||||
d0.set_as_af(d0.af_num(), DATA_AF);
|
set_as_af!(d0, DATA_AF);
|
||||||
});
|
});
|
||||||
|
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
@ -586,12 +586,12 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
|
|||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
clk.set_as_af(clk.af_num(), CLK_AF);
|
set_as_af!(clk, CLK_AF);
|
||||||
cmd.set_as_af(cmd.af_num(), CMD_AF);
|
set_as_af!(cmd, CMD_AF);
|
||||||
d0.set_as_af(d0.af_num(), DATA_AF);
|
set_as_af!(d0, DATA_AF);
|
||||||
d1.set_as_af(d1.af_num(), DATA_AF);
|
set_as_af!(d1, DATA_AF);
|
||||||
d2.set_as_af(d2.af_num(), DATA_AF);
|
set_as_af!(d2, DATA_AF);
|
||||||
d3.set_as_af(d3.af_num(), DATA_AF);
|
set_as_af!(d3, DATA_AF);
|
||||||
});
|
});
|
||||||
|
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
@ -630,16 +630,16 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
|
|||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
clk.set_as_af(clk.af_num(), CLK_AF);
|
set_as_af!(clk, CLK_AF);
|
||||||
cmd.set_as_af(cmd.af_num(), CMD_AF);
|
set_as_af!(cmd, CMD_AF);
|
||||||
d0.set_as_af(d0.af_num(), DATA_AF);
|
set_as_af!(d0, DATA_AF);
|
||||||
d1.set_as_af(d1.af_num(), DATA_AF);
|
set_as_af!(d1, DATA_AF);
|
||||||
d2.set_as_af(d2.af_num(), DATA_AF);
|
set_as_af!(d2, DATA_AF);
|
||||||
d3.set_as_af(d3.af_num(), DATA_AF);
|
set_as_af!(d3, DATA_AF);
|
||||||
d4.set_as_af(d4.af_num(), DATA_AF);
|
set_as_af!(d4, DATA_AF);
|
||||||
d5.set_as_af(d5.af_num(), DATA_AF);
|
set_as_af!(d5, DATA_AF);
|
||||||
d6.set_as_af(d6.af_num(), DATA_AF);
|
set_as_af!(d6, DATA_AF);
|
||||||
d7.set_as_af(d7.af_num(), DATA_AF);
|
set_as_af!(d7, DATA_AF);
|
||||||
});
|
});
|
||||||
|
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
|
@ -35,7 +35,7 @@ macro_rules! new_spdifrx_pin {
|
|||||||
($name:ident, $af_type:expr) => {{
|
($name:ident, $af_type:expr) => {{
|
||||||
let pin = $name;
|
let pin = $name;
|
||||||
let input_sel = pin.input_sel();
|
let input_sel = pin.input_sel();
|
||||||
pin.set_as_af(pin.af_num(), $af_type);
|
set_as_af!(pin, $af_type);
|
||||||
(Some(pin.into()), input_sel)
|
(Some(pin.into()), input_sel)
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
@ -471,11 +471,11 @@ impl<'d, M: PeriMode> Spi<'d, M> {
|
|||||||
|
|
||||||
impl<'d> Spi<'d, Blocking> {
|
impl<'d> Spi<'d, Blocking> {
|
||||||
/// Create a new blocking SPI driver.
|
/// Create a new blocking SPI driver.
|
||||||
pub fn new_blocking<T: Instance>(
|
pub fn new_blocking<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
sck: Peri<'d, impl SckPin<T>>,
|
sck: Peri<'d, if_afio!(impl SckPin<T, A>)>,
|
||||||
mosi: Peri<'d, impl MosiPin<T>>,
|
mosi: Peri<'d, if_afio!(impl MosiPin<T, A>)>,
|
||||||
miso: Peri<'d, impl MisoPin<T>>,
|
miso: Peri<'d, if_afio!(impl MisoPin<T, A>)>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
@ -490,10 +490,10 @@ impl<'d> Spi<'d, Blocking> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new blocking SPI driver, in RX-only mode (only MISO pin, no MOSI).
|
/// Create a new blocking SPI driver, in RX-only mode (only MISO pin, no MOSI).
|
||||||
pub fn new_blocking_rxonly<T: Instance>(
|
pub fn new_blocking_rxonly<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
sck: Peri<'d, impl SckPin<T>>,
|
sck: Peri<'d, if_afio!(impl SckPin<T, A>)>,
|
||||||
miso: Peri<'d, impl MisoPin<T>>,
|
miso: Peri<'d, if_afio!(impl MisoPin<T, A>)>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
@ -508,10 +508,10 @@ impl<'d> Spi<'d, Blocking> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new blocking SPI driver, in TX-only mode (only MOSI pin, no MISO).
|
/// Create a new blocking SPI driver, in TX-only mode (only MOSI pin, no MISO).
|
||||||
pub fn new_blocking_txonly<T: Instance>(
|
pub fn new_blocking_txonly<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
sck: Peri<'d, impl SckPin<T>>,
|
sck: Peri<'d, if_afio!(impl SckPin<T, A>)>,
|
||||||
mosi: Peri<'d, impl MosiPin<T>>,
|
mosi: Peri<'d, if_afio!(impl MosiPin<T, A>)>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
@ -528,9 +528,9 @@ impl<'d> Spi<'d, Blocking> {
|
|||||||
/// Create a new SPI driver, in TX-only mode, without SCK pin.
|
/// Create a new SPI driver, in TX-only mode, without SCK pin.
|
||||||
///
|
///
|
||||||
/// This can be useful for bit-banging non-SPI protocols.
|
/// This can be useful for bit-banging non-SPI protocols.
|
||||||
pub fn new_blocking_txonly_nosck<T: Instance>(
|
pub fn new_blocking_txonly_nosck<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
mosi: Peri<'d, impl MosiPin<T>>,
|
mosi: Peri<'d, if_afio!(impl MosiPin<T, A>)>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
@ -547,11 +547,11 @@ impl<'d> Spi<'d, Blocking> {
|
|||||||
|
|
||||||
impl<'d> Spi<'d, Async> {
|
impl<'d> Spi<'d, Async> {
|
||||||
/// Create a new SPI driver.
|
/// Create a new SPI driver.
|
||||||
pub fn new<T: Instance>(
|
pub fn new<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
sck: Peri<'d, impl SckPin<T>>,
|
sck: Peri<'d, if_afio!(impl SckPin<T, A>)>,
|
||||||
mosi: Peri<'d, impl MosiPin<T>>,
|
mosi: Peri<'d, if_afio!(impl MosiPin<T, A>)>,
|
||||||
miso: Peri<'d, impl MisoPin<T>>,
|
miso: Peri<'d, if_afio!(impl MisoPin<T, A>)>,
|
||||||
tx_dma: Peri<'d, impl TxDma<T>>,
|
tx_dma: Peri<'d, impl TxDma<T>>,
|
||||||
rx_dma: Peri<'d, impl RxDma<T>>,
|
rx_dma: Peri<'d, impl RxDma<T>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
@ -568,10 +568,10 @@ impl<'d> Spi<'d, Async> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new SPI driver, in RX-only mode (only MISO pin, no MOSI).
|
/// Create a new SPI driver, in RX-only mode (only MISO pin, no MOSI).
|
||||||
pub fn new_rxonly<T: Instance>(
|
pub fn new_rxonly<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
sck: Peri<'d, impl SckPin<T>>,
|
sck: Peri<'d, if_afio!(impl SckPin<T, A>)>,
|
||||||
miso: Peri<'d, impl MisoPin<T>>,
|
miso: Peri<'d, if_afio!(impl MisoPin<T, A>)>,
|
||||||
#[cfg(any(spi_v1, spi_v2, spi_v3))] tx_dma: Peri<'d, impl TxDma<T>>,
|
#[cfg(any(spi_v1, spi_v2, spi_v3))] tx_dma: Peri<'d, impl TxDma<T>>,
|
||||||
rx_dma: Peri<'d, impl RxDma<T>>,
|
rx_dma: Peri<'d, impl RxDma<T>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
@ -591,10 +591,10 @@ impl<'d> Spi<'d, Async> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new SPI driver, in TX-only mode (only MOSI pin, no MISO).
|
/// Create a new SPI driver, in TX-only mode (only MOSI pin, no MISO).
|
||||||
pub fn new_txonly<T: Instance>(
|
pub fn new_txonly<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
sck: Peri<'d, impl SckPin<T>>,
|
sck: Peri<'d, if_afio!(impl SckPin<T, A>)>,
|
||||||
mosi: Peri<'d, impl MosiPin<T>>,
|
mosi: Peri<'d, if_afio!(impl MosiPin<T, A>)>,
|
||||||
tx_dma: Peri<'d, impl TxDma<T>>,
|
tx_dma: Peri<'d, impl TxDma<T>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@ -612,9 +612,9 @@ impl<'d> Spi<'d, Async> {
|
|||||||
/// Create a new SPI driver, in TX-only mode, without SCK pin.
|
/// Create a new SPI driver, in TX-only mode, without SCK pin.
|
||||||
///
|
///
|
||||||
/// This can be useful for bit-banging non-SPI protocols.
|
/// This can be useful for bit-banging non-SPI protocols.
|
||||||
pub fn new_txonly_nosck<T: Instance>(
|
pub fn new_txonly_nosck<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
mosi: Peri<'d, impl MosiPin<T>>,
|
mosi: Peri<'d, if_afio!(impl MosiPin<T, A>)>,
|
||||||
tx_dma: Peri<'d, impl TxDma<T>>,
|
tx_dma: Peri<'d, impl TxDma<T>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@ -1309,13 +1309,13 @@ impl State {
|
|||||||
|
|
||||||
peri_trait!();
|
peri_trait!();
|
||||||
|
|
||||||
pin_trait!(SckPin, Instance);
|
pin_trait!(SckPin, Instance, @A);
|
||||||
pin_trait!(MosiPin, Instance);
|
pin_trait!(MosiPin, Instance, @A);
|
||||||
pin_trait!(MisoPin, Instance);
|
pin_trait!(MisoPin, Instance, @A);
|
||||||
pin_trait!(CsPin, Instance);
|
pin_trait!(CsPin, Instance, @A);
|
||||||
pin_trait!(MckPin, Instance);
|
pin_trait!(MckPin, Instance, @A);
|
||||||
pin_trait!(CkPin, Instance);
|
pin_trait!(CkPin, Instance, @A);
|
||||||
pin_trait!(WsPin, Instance);
|
pin_trait!(WsPin, Instance, @A);
|
||||||
dma_trait!(RxDma, Instance);
|
dma_trait!(RxDma, Instance);
|
||||||
dma_trait!(TxDma, Instance);
|
dma_trait!(TxDma, Instance);
|
||||||
|
|
||||||
|
@ -16,23 +16,24 @@ use crate::Peri;
|
|||||||
/// Complementary PWM pin wrapper.
|
/// Complementary PWM pin wrapper.
|
||||||
///
|
///
|
||||||
/// This wraps a pin to make it usable with PWM.
|
/// This wraps a pin to make it usable with PWM.
|
||||||
pub struct ComplementaryPwmPin<'d, T, C> {
|
pub struct ComplementaryPwmPin<'d, T, C, #[cfg(afio)] A> {
|
||||||
_pin: Peri<'d, AnyPin>,
|
#[allow(unused)]
|
||||||
phantom: PhantomData<(T, C)>,
|
pin: Peri<'d, AnyPin>,
|
||||||
|
phantom: PhantomData<if_afio!((T, C, A))>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: AdvancedInstance4Channel, C: TimerChannel> ComplementaryPwmPin<'d, T, C> {
|
impl<'d, T: AdvancedInstance4Channel, C: TimerChannel, #[cfg(afio)] A> if_afio!(ComplementaryPwmPin<'d, T, C, A>) {
|
||||||
/// Create a new complementary PWM pin instance.
|
/// Create a new complementary PWM pin instance.
|
||||||
pub fn new(pin: Peri<'d, impl TimerComplementaryPin<T, C>>, output_type: OutputType) -> Self {
|
pub fn new(pin: Peri<'d, if_afio!(impl TimerComplementaryPin<T, C, A>)>, output_type: OutputType) -> Self {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
pin.set_low();
|
pin.set_low();
|
||||||
pin.set_as_af(
|
set_as_af!(
|
||||||
pin.af_num(),
|
pin,
|
||||||
crate::gpio::AfType::output(output_type, crate::gpio::Speed::VeryHigh),
|
crate::gpio::AfType::output(output_type, crate::gpio::Speed::VeryHigh)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
ComplementaryPwmPin {
|
ComplementaryPwmPin {
|
||||||
_pin: pin.into(),
|
pin: pin.into(),
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,17 +55,17 @@ pub enum IdlePolarity {
|
|||||||
|
|
||||||
impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
|
impl<'d, T: AdvancedInstance4Channel> ComplementaryPwm<'d, T> {
|
||||||
/// Create a new complementary PWM driver.
|
/// Create a new complementary PWM driver.
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments, unused)]
|
||||||
pub fn new(
|
pub fn new<#[cfg(afio)] A>(
|
||||||
tim: Peri<'d, T>,
|
tim: Peri<'d, T>,
|
||||||
_ch1: Option<PwmPin<'d, T, Ch1>>,
|
ch1: Option<if_afio!(PwmPin<'d, T, Ch1, A>)>,
|
||||||
_ch1n: Option<ComplementaryPwmPin<'d, T, Ch1>>,
|
ch1n: Option<if_afio!(ComplementaryPwmPin<'d, T, Ch1, A>)>,
|
||||||
_ch2: Option<PwmPin<'d, T, Ch2>>,
|
ch2: Option<if_afio!(PwmPin<'d, T, Ch2, A>)>,
|
||||||
_ch2n: Option<ComplementaryPwmPin<'d, T, Ch2>>,
|
ch2n: Option<if_afio!(ComplementaryPwmPin<'d, T, Ch2, A>)>,
|
||||||
_ch3: Option<PwmPin<'d, T, Ch3>>,
|
ch3: Option<if_afio!(PwmPin<'d, T, Ch3, A>)>,
|
||||||
_ch3n: Option<ComplementaryPwmPin<'d, T, Ch3>>,
|
ch3n: Option<if_afio!(ComplementaryPwmPin<'d, T, Ch3, A>)>,
|
||||||
_ch4: Option<PwmPin<'d, T, Ch4>>,
|
ch4: Option<if_afio!(PwmPin<'d, T, Ch4, A>)>,
|
||||||
_ch4n: Option<ComplementaryPwmPin<'d, T, Ch4>>,
|
ch4n: Option<if_afio!(ComplementaryPwmPin<'d, T, Ch4, A>)>,
|
||||||
freq: Hertz,
|
freq: Hertz,
|
||||||
counting_mode: CountingMode,
|
counting_mode: CountingMode,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -17,16 +17,17 @@ use crate::Peri;
|
|||||||
/// Capture pin wrapper.
|
/// Capture pin wrapper.
|
||||||
///
|
///
|
||||||
/// This wraps a pin to make it usable with capture.
|
/// This wraps a pin to make it usable with capture.
|
||||||
pub struct CapturePin<'d, T, C> {
|
pub struct CapturePin<'d, T, C, #[cfg(afio)] A> {
|
||||||
_pin: Peri<'d, AnyPin>,
|
#[allow(unused)]
|
||||||
phantom: PhantomData<(T, C)>,
|
pin: Peri<'d, AnyPin>,
|
||||||
|
phantom: PhantomData<if_afio!((T, C, A))>,
|
||||||
}
|
}
|
||||||
impl<'d, T: GeneralInstance4Channel, C: TimerChannel> CapturePin<'d, T, C> {
|
impl<'d, T: GeneralInstance4Channel, C: TimerChannel, #[cfg(afio)] A> if_afio!(CapturePin<'d, T, C, A>) {
|
||||||
/// Create a new capture pin instance.
|
/// Create a new capture pin instance.
|
||||||
pub fn new(pin: Peri<'d, impl TimerPin<T, C>>, pull: Pull) -> Self {
|
pub fn new(pin: Peri<'d, if_afio!(impl TimerPin<T, C, A>)>, pull: Pull) -> Self {
|
||||||
pin.set_as_af(pin.af_num(), AfType::input(pull));
|
set_as_af!(pin, AfType::input(pull));
|
||||||
CapturePin {
|
CapturePin {
|
||||||
_pin: pin.into(),
|
pin: pin.into(),
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -39,12 +40,13 @@ pub struct InputCapture<'d, T: GeneralInstance4Channel> {
|
|||||||
|
|
||||||
impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> {
|
impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> {
|
||||||
/// Create a new input capture driver.
|
/// Create a new input capture driver.
|
||||||
pub fn new(
|
#[allow(unused)]
|
||||||
|
pub fn new<#[cfg(afio)] A>(
|
||||||
tim: Peri<'d, T>,
|
tim: Peri<'d, T>,
|
||||||
_ch1: Option<CapturePin<'d, T, Ch1>>,
|
ch1: Option<if_afio!(CapturePin<'d, T, Ch1, A>)>,
|
||||||
_ch2: Option<CapturePin<'d, T, Ch2>>,
|
ch2: Option<if_afio!(CapturePin<'d, T, Ch2, A>)>,
|
||||||
_ch3: Option<CapturePin<'d, T, Ch3>>,
|
ch3: Option<if_afio!(CapturePin<'d, T, Ch3, A>)>,
|
||||||
_ch4: Option<CapturePin<'d, T, Ch4>>,
|
ch4: Option<if_afio!(CapturePin<'d, T, Ch4, A>)>,
|
||||||
_irq: impl Binding<T::CaptureCompareInterrupt, CaptureCompareInterruptHandler<T>> + 'd,
|
_irq: impl Binding<T::CaptureCompareInterrupt, CaptureCompareInterruptHandler<T>> + 'd,
|
||||||
freq: Hertz,
|
freq: Hertz,
|
||||||
counting_mode: CountingMode,
|
counting_mode: CountingMode,
|
||||||
|
@ -223,15 +223,15 @@ pub trait AdvancedInstance2Channel: BasicInstance + GeneralInstance2Channel + Ad
|
|||||||
/// Advanced 16-bit timer with 4 channels instance.
|
/// Advanced 16-bit timer with 4 channels instance.
|
||||||
pub trait AdvancedInstance4Channel: AdvancedInstance2Channel + GeneralInstance4Channel {}
|
pub trait AdvancedInstance4Channel: AdvancedInstance2Channel + GeneralInstance4Channel {}
|
||||||
|
|
||||||
pin_trait!(TimerPin, GeneralInstance4Channel, TimerChannel);
|
pin_trait!(TimerPin, GeneralInstance4Channel, TimerChannel, @A);
|
||||||
pin_trait!(ExternalTriggerPin, GeneralInstance4Channel);
|
pin_trait!(ExternalTriggerPin, GeneralInstance4Channel, @A);
|
||||||
|
|
||||||
pin_trait!(TimerComplementaryPin, AdvancedInstance4Channel, TimerChannel);
|
pin_trait!(TimerComplementaryPin, AdvancedInstance4Channel, TimerChannel, @A);
|
||||||
|
|
||||||
pin_trait!(BreakInputPin, AdvancedInstance4Channel, BreakInput);
|
pin_trait!(BreakInputPin, AdvancedInstance4Channel, BreakInput, @A);
|
||||||
|
|
||||||
pin_trait!(BreakInputComparator1Pin, AdvancedInstance4Channel, BreakInput);
|
pin_trait!(BreakInputComparator1Pin, AdvancedInstance4Channel, BreakInput, @A);
|
||||||
pin_trait!(BreakInputComparator2Pin, AdvancedInstance4Channel, BreakInput);
|
pin_trait!(BreakInputComparator2Pin, AdvancedInstance4Channel, BreakInput, @A);
|
||||||
|
|
||||||
// Update Event trigger DMA for every timer
|
// Update Event trigger DMA for every timer
|
||||||
dma_trait!(UpDma, BasicInstance);
|
dma_trait!(UpDma, BasicInstance);
|
||||||
|
@ -15,6 +15,7 @@ use crate::gpio::{AfType, AnyPin, Pull};
|
|||||||
use crate::interrupt::typelevel::{Binding, Interrupt};
|
use crate::interrupt::typelevel::{Binding, Interrupt};
|
||||||
use crate::pac::timer::vals::Etp;
|
use crate::pac::timer::vals::Etp;
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
|
use crate::timer::TimerChannel;
|
||||||
use crate::Peri;
|
use crate::Peri;
|
||||||
|
|
||||||
/// External input marker type.
|
/// External input marker type.
|
||||||
@ -42,7 +43,8 @@ impl From<ExternalTriggerPolarity> for Etp {
|
|||||||
///
|
///
|
||||||
/// This wraps a pin to make it usable as a timer trigger.
|
/// This wraps a pin to make it usable as a timer trigger.
|
||||||
pub struct TriggerPin<'d, T, C> {
|
pub struct TriggerPin<'d, T, C> {
|
||||||
_pin: Peri<'d, AnyPin>,
|
#[allow(unused)]
|
||||||
|
pin: Peri<'d, AnyPin>,
|
||||||
phantom: PhantomData<(T, C)>,
|
phantom: PhantomData<(T, C)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,60 +62,23 @@ impl SealedTriggerSource for Ch1 {}
|
|||||||
impl SealedTriggerSource for Ch2 {}
|
impl SealedTriggerSource for Ch2 {}
|
||||||
impl SealedTriggerSource for Ext {}
|
impl SealedTriggerSource for Ext {}
|
||||||
|
|
||||||
trait SealedTimerTriggerPin<T, S>: crate::gpio::Pin {}
|
impl<'d, T: GeneralInstance4Channel, C: TriggerSource + TimerChannel> TriggerPin<'d, T, C> {
|
||||||
|
/// Create a new Channel trigger pin instance.
|
||||||
/// Marker trait for a trigger pin.
|
pub fn new<#[cfg(afio)] A>(pin: Peri<'d, if_afio!(impl TimerPin<T, C, A>)>, pull: Pull) -> Self {
|
||||||
#[expect(private_bounds)]
|
set_as_af!(pin, AfType::input(pull));
|
||||||
// TODO: find better naming scheme than prefixing all pin traits with "Timer".
|
|
||||||
// The trait name cannot conflict with the corresponding type's name.
|
|
||||||
// Applies to other timer submodules as well.
|
|
||||||
pub trait TimerTriggerPin<T, S>: SealedTimerTriggerPin<T, S> {
|
|
||||||
/// Get the AF number needed to use this pin as a trigger source.
|
|
||||||
fn af_num(&self) -> u8;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, P, C> TimerTriggerPin<T, C> for P
|
|
||||||
where
|
|
||||||
T: GeneralInstance4Channel,
|
|
||||||
P: TimerPin<T, C>,
|
|
||||||
C: super::TimerChannel + TriggerSource,
|
|
||||||
{
|
|
||||||
fn af_num(&self) -> u8 {
|
|
||||||
TimerPin::af_num(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, P> TimerTriggerPin<T, Ext> for P
|
|
||||||
where
|
|
||||||
T: GeneralInstance4Channel,
|
|
||||||
P: ExternalTriggerPin<T>,
|
|
||||||
{
|
|
||||||
fn af_num(&self) -> u8 {
|
|
||||||
ExternalTriggerPin::af_num(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, P, C> SealedTimerTriggerPin<T, C> for P
|
|
||||||
where
|
|
||||||
T: GeneralInstance4Channel,
|
|
||||||
P: TimerPin<T, C>,
|
|
||||||
C: super::TimerChannel + TriggerSource,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, P> SealedTimerTriggerPin<T, Ext> for P
|
|
||||||
where
|
|
||||||
T: GeneralInstance4Channel,
|
|
||||||
P: ExternalTriggerPin<T>,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: GeneralInstance4Channel, C: TriggerSource> TriggerPin<'d, T, C> {
|
|
||||||
/// "Create a new Ch1 trigger pin instance.
|
|
||||||
pub fn new(pin: Peri<'d, impl TimerTriggerPin<T, C>>, pull: Pull) -> Self {
|
|
||||||
pin.set_as_af(pin.af_num(), AfType::input(pull));
|
|
||||||
TriggerPin {
|
TriggerPin {
|
||||||
_pin: pin.into(),
|
pin: pin.into(),
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: GeneralInstance4Channel> TriggerPin<'d, T, Ext> {
|
||||||
|
/// Create a new external trigger pin instance.
|
||||||
|
pub fn new_external<#[cfg(afio)] A>(pin: Peri<'d, if_afio!(impl ExternalTriggerPin<T, A>)>, pull: Pull) -> Self {
|
||||||
|
set_as_af!(pin, AfType::input(pull));
|
||||||
|
TriggerPin {
|
||||||
|
pin: pin.into(),
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,9 +96,10 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> {
|
|||||||
///
|
///
|
||||||
/// The pulse is triggered by a channel 1 input pin on both rising and
|
/// The pulse is triggered by a channel 1 input pin on both rising and
|
||||||
/// falling edges. Channel 1 will unusable as an output.
|
/// falling edges. Channel 1 will unusable as an output.
|
||||||
|
#[allow(unused)]
|
||||||
pub fn new_ch1_edge_detect(
|
pub fn new_ch1_edge_detect(
|
||||||
tim: Peri<'d, T>,
|
tim: Peri<'d, T>,
|
||||||
_pin: TriggerPin<'d, T, Ch1>,
|
pin: TriggerPin<'d, T, Ch1>,
|
||||||
_irq: impl Binding<T::CaptureCompareInterrupt, CaptureCompareInterruptHandler<T>> + 'd,
|
_irq: impl Binding<T::CaptureCompareInterrupt, CaptureCompareInterruptHandler<T>> + 'd,
|
||||||
freq: Hertz,
|
freq: Hertz,
|
||||||
pulse_end: u32,
|
pulse_end: u32,
|
||||||
|
@ -18,15 +18,25 @@ pub struct PwmInput<'d, T: GeneralInstance4Channel> {
|
|||||||
|
|
||||||
impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> {
|
impl<'d, T: GeneralInstance4Channel> PwmInput<'d, T> {
|
||||||
/// Create a new PWM input driver.
|
/// Create a new PWM input driver.
|
||||||
pub fn new_ch1(tim: Peri<'d, T>, pin: Peri<'d, impl TimerPin<T, Ch1>>, pull: Pull, freq: Hertz) -> Self {
|
pub fn new_ch1<#[cfg(afio)] A>(
|
||||||
pin.set_as_af(pin.af_num(), AfType::input(pull));
|
tim: Peri<'d, T>,
|
||||||
|
pin: Peri<'d, if_afio!(impl TimerPin<T, Ch1, A>)>,
|
||||||
|
pull: Pull,
|
||||||
|
freq: Hertz,
|
||||||
|
) -> Self {
|
||||||
|
set_as_af!(pin, AfType::input(pull));
|
||||||
|
|
||||||
Self::new_inner(tim, freq, Channel::Ch1, Channel::Ch2)
|
Self::new_inner(tim, freq, Channel::Ch1, Channel::Ch2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new PWM input driver.
|
/// Create a new PWM input driver.
|
||||||
pub fn new_ch2(tim: Peri<'d, T>, pin: Peri<'d, impl TimerPin<T, Ch2>>, pull: Pull, freq: Hertz) -> Self {
|
pub fn new_ch2<#[cfg(afio)] A>(
|
||||||
pin.set_as_af(pin.af_num(), AfType::input(pull));
|
tim: Peri<'d, T>,
|
||||||
|
pin: Peri<'d, if_afio!(impl TimerPin<T, Ch2, A>)>,
|
||||||
|
pull: Pull,
|
||||||
|
freq: Hertz,
|
||||||
|
) -> Self {
|
||||||
|
set_as_af!(pin, AfType::input(pull));
|
||||||
|
|
||||||
Self::new_inner(tim, freq, Channel::Ch2, Channel::Ch1)
|
Self::new_inner(tim, freq, Channel::Ch2, Channel::Ch1)
|
||||||
}
|
}
|
||||||
|
@ -20,20 +20,21 @@ pub enum Direction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Wrapper for using a pin with QEI.
|
/// Wrapper for using a pin with QEI.
|
||||||
pub struct QeiPin<'d, T, Channel> {
|
pub struct QeiPin<'d, T, Channel, #[cfg(afio)] A> {
|
||||||
_pin: Peri<'d, AnyPin>,
|
#[allow(unused)]
|
||||||
phantom: PhantomData<(T, Channel)>,
|
pin: Peri<'d, AnyPin>,
|
||||||
|
phantom: PhantomData<if_afio!((T, Channel, A))>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: GeneralInstance4Channel, C: QeiChannel> QeiPin<'d, T, C> {
|
impl<'d, T: GeneralInstance4Channel, C: QeiChannel, #[cfg(afio)] A> if_afio!(QeiPin<'d, T, C, A>) {
|
||||||
/// Create a new QEI pin instance.
|
/// Create a new QEI pin instance.
|
||||||
pub fn new(pin: Peri<'d, impl TimerPin<T, C>>) -> Self {
|
pub fn new(pin: Peri<'d, if_afio!(impl TimerPin<T, C, A>)>) -> Self {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
pin.set_low();
|
pin.set_low();
|
||||||
pin.set_as_af(pin.af_num(), AfType::input(Pull::None));
|
set_as_af!(pin, AfType::input(Pull::None));
|
||||||
});
|
});
|
||||||
QeiPin {
|
QeiPin {
|
||||||
_pin: pin.into(),
|
pin: pin.into(),
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,7 +59,12 @@ pub struct Qei<'d, T: GeneralInstance4Channel> {
|
|||||||
|
|
||||||
impl<'d, T: GeneralInstance4Channel> Qei<'d, T> {
|
impl<'d, T: GeneralInstance4Channel> Qei<'d, T> {
|
||||||
/// Create a new quadrature decoder driver.
|
/// Create a new quadrature decoder driver.
|
||||||
pub fn new(tim: Peri<'d, T>, _ch1: QeiPin<'d, T, Ch1>, _ch2: QeiPin<'d, T, Ch2>) -> Self {
|
#[allow(unused)]
|
||||||
|
pub fn new<#[cfg(afio)] A>(
|
||||||
|
tim: Peri<'d, T>,
|
||||||
|
ch1: if_afio!(QeiPin<'d, T, Ch1, A>),
|
||||||
|
ch2: if_afio!(QeiPin<'d, T, Ch2, A>),
|
||||||
|
) -> Self {
|
||||||
Self::new_inner(tim)
|
Self::new_inner(tim)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,9 +14,10 @@ use crate::Peri;
|
|||||||
/// PWM pin wrapper.
|
/// PWM pin wrapper.
|
||||||
///
|
///
|
||||||
/// This wraps a pin to make it usable with PWM.
|
/// This wraps a pin to make it usable with PWM.
|
||||||
pub struct PwmPin<'d, T, C> {
|
pub struct PwmPin<'d, T, C, #[cfg(afio)] A> {
|
||||||
_pin: Peri<'d, AnyPin>,
|
#[allow(unused)]
|
||||||
phantom: PhantomData<(T, C)>,
|
pub(crate) pin: Peri<'d, AnyPin>,
|
||||||
|
phantom: PhantomData<if_afio!((T, C, A))>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PWM pin config
|
/// PWM pin config
|
||||||
@ -34,33 +35,33 @@ pub struct PwmPinConfig {
|
|||||||
pub pull: Pull,
|
pub pull: Pull,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: GeneralInstance4Channel, C: TimerChannel> PwmPin<'d, T, C> {
|
impl<'d, T: GeneralInstance4Channel, C: TimerChannel, #[cfg(afio)] A> if_afio!(PwmPin<'d, T, C, A>) {
|
||||||
/// Create a new PWM pin instance.
|
/// Create a new PWM pin instance.
|
||||||
pub fn new(pin: Peri<'d, impl TimerPin<T, C>>, output_type: OutputType) -> Self {
|
pub fn new(pin: Peri<'d, if_afio!(impl TimerPin<T, C, A>)>, output_type: OutputType) -> Self {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
pin.set_low();
|
pin.set_low();
|
||||||
pin.set_as_af(pin.af_num(), AfType::output(output_type, Speed::VeryHigh));
|
set_as_af!(pin, AfType::output(output_type, Speed::VeryHigh));
|
||||||
});
|
});
|
||||||
PwmPin {
|
PwmPin {
|
||||||
_pin: pin.into(),
|
pin: pin.into(),
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new PWM pin instance with config.
|
/// Create a new PWM pin instance with a specific configuration.
|
||||||
pub fn new_with_config(pin: Peri<'d, impl TimerPin<T, C>>, pin_config: PwmPinConfig) -> Self {
|
pub fn new_with_config(pin: Peri<'d, if_afio!(impl TimerPin<T, C, A>)>, pin_config: PwmPinConfig) -> Self {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
pin.set_low();
|
pin.set_low();
|
||||||
pin.set_as_af(
|
#[cfg(gpio_v1)]
|
||||||
pin.af_num(),
|
set_as_af!(pin, AfType::output(pin_config.output_type, pin_config.speed));
|
||||||
#[cfg(gpio_v1)]
|
#[cfg(gpio_v2)]
|
||||||
AfType::output(pin_config.output_type, pin_config.speed),
|
set_as_af!(
|
||||||
#[cfg(gpio_v2)]
|
pin,
|
||||||
AfType::output_pull(pin_config.output_type, pin_config.speed, pin_config.pull),
|
AfType::output_pull(pin_config.output_type, pin_config.speed, pin_config.pull)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
PwmPin {
|
PwmPin {
|
||||||
_pin: pin.into(),
|
pin: pin.into(),
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,12 +179,13 @@ pub struct SimplePwm<'d, T: GeneralInstance4Channel> {
|
|||||||
|
|
||||||
impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
|
impl<'d, T: GeneralInstance4Channel> SimplePwm<'d, T> {
|
||||||
/// Create a new simple PWM driver.
|
/// Create a new simple PWM driver.
|
||||||
pub fn new(
|
#[allow(unused)]
|
||||||
|
pub fn new<#[cfg(afio)] A>(
|
||||||
tim: Peri<'d, T>,
|
tim: Peri<'d, T>,
|
||||||
_ch1: Option<PwmPin<'d, T, Ch1>>,
|
ch1: Option<if_afio!(PwmPin<'d, T, Ch1, A>)>,
|
||||||
_ch2: Option<PwmPin<'d, T, Ch2>>,
|
ch2: Option<if_afio!(PwmPin<'d, T, Ch2, A>)>,
|
||||||
_ch3: Option<PwmPin<'d, T, Ch3>>,
|
ch3: Option<if_afio!(PwmPin<'d, T, Ch3, A>)>,
|
||||||
_ch4: Option<PwmPin<'d, T, Ch4>>,
|
ch4: Option<if_afio!(PwmPin<'d, T, Ch4, A>)>,
|
||||||
freq: Hertz,
|
freq: Hertz,
|
||||||
counting_mode: CountingMode,
|
counting_mode: CountingMode,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -427,7 +427,7 @@ macro_rules! impl_set_io {
|
|||||||
pub fn $method<Role: pin_roles::Role>(&mut self, pin: Peri<'d, impl $trait<T>>) -> IOPinWithRole<$group, Role> {
|
pub fn $method<Role: pin_roles::Role>(&mut self, pin: Peri<'d, impl $trait<T>>) -> IOPinWithRole<$group, Role> {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
pin.set_low();
|
pin.set_low();
|
||||||
pin.set_as_af(pin.af_num(), AfType::output(Role::output_type(), Speed::VeryHigh));
|
set_as_af!(pin, AfType::output(Role::output_type(), Speed::VeryHigh));
|
||||||
let tsc_io_pin = trait_to_io_pin!($trait);
|
let tsc_io_pin = trait_to_io_pin!($trait);
|
||||||
let new_pin = Pin {
|
let new_pin = Pin {
|
||||||
_pin: pin.into(),
|
_pin: pin.into(),
|
||||||
|
@ -208,10 +208,10 @@ impl<'d> SetConfig for BufferedUartTx<'d> {
|
|||||||
|
|
||||||
impl<'d> BufferedUart<'d> {
|
impl<'d> BufferedUart<'d> {
|
||||||
/// Create a new bidirectional buffered UART driver
|
/// Create a new bidirectional buffered UART driver
|
||||||
pub fn new<T: Instance>(
|
pub fn new<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
rx: Peri<'d, impl RxPin<T>>,
|
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
|
||||||
tx: Peri<'d, impl TxPin<T>>,
|
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
|
||||||
tx_buffer: &'d mut [u8],
|
tx_buffer: &'d mut [u8],
|
||||||
rx_buffer: &'d mut [u8],
|
rx_buffer: &'d mut [u8],
|
||||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
@ -231,12 +231,12 @@ impl<'d> BufferedUart<'d> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new bidirectional buffered UART driver with request-to-send and clear-to-send pins
|
/// Create a new bidirectional buffered UART driver with request-to-send and clear-to-send pins
|
||||||
pub fn new_with_rtscts<T: Instance>(
|
pub fn new_with_rtscts<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
rx: Peri<'d, impl RxPin<T>>,
|
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
|
||||||
tx: Peri<'d, impl TxPin<T>>,
|
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
|
||||||
rts: Peri<'d, impl RtsPin<T>>,
|
rts: Peri<'d, if_afio!(impl RtsPin<T, A>)>,
|
||||||
cts: Peri<'d, impl CtsPin<T>>,
|
cts: Peri<'d, if_afio!(impl CtsPin<T, A>)>,
|
||||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
tx_buffer: &'d mut [u8],
|
tx_buffer: &'d mut [u8],
|
||||||
rx_buffer: &'d mut [u8],
|
rx_buffer: &'d mut [u8],
|
||||||
@ -256,11 +256,11 @@ impl<'d> BufferedUart<'d> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new bidirectional buffered UART driver with only the RTS pin as the DE pin
|
/// Create a new bidirectional buffered UART driver with only the RTS pin as the DE pin
|
||||||
pub fn new_with_rts_as_de<T: Instance>(
|
pub fn new_with_rts_as_de<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
rx: Peri<'d, impl RxPin<T>>,
|
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
|
||||||
tx: Peri<'d, impl TxPin<T>>,
|
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
|
||||||
rts: Peri<'d, impl RtsPin<T>>,
|
rts: Peri<'d, if_afio!(impl RtsPin<T, A>)>,
|
||||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
tx_buffer: &'d mut [u8],
|
tx_buffer: &'d mut [u8],
|
||||||
rx_buffer: &'d mut [u8],
|
rx_buffer: &'d mut [u8],
|
||||||
@ -280,11 +280,11 @@ impl<'d> BufferedUart<'d> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new bidirectional buffered UART driver with only the request-to-send pin
|
/// Create a new bidirectional buffered UART driver with only the request-to-send pin
|
||||||
pub fn new_with_rts<T: Instance>(
|
pub fn new_with_rts<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
rx: Peri<'d, impl RxPin<T>>,
|
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
|
||||||
tx: Peri<'d, impl TxPin<T>>,
|
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
|
||||||
rts: Peri<'d, impl RtsPin<T>>,
|
rts: Peri<'d, if_afio!(impl RtsPin<T, A>)>,
|
||||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
tx_buffer: &'d mut [u8],
|
tx_buffer: &'d mut [u8],
|
||||||
rx_buffer: &'d mut [u8],
|
rx_buffer: &'d mut [u8],
|
||||||
@ -305,11 +305,11 @@ impl<'d> BufferedUart<'d> {
|
|||||||
|
|
||||||
/// Create a new bidirectional buffered UART driver with a driver-enable pin
|
/// Create a new bidirectional buffered UART driver with a driver-enable pin
|
||||||
#[cfg(not(any(usart_v1, usart_v2)))]
|
#[cfg(not(any(usart_v1, usart_v2)))]
|
||||||
pub fn new_with_de<T: Instance>(
|
pub fn new_with_de<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
rx: Peri<'d, impl RxPin<T>>,
|
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
|
||||||
tx: Peri<'d, impl TxPin<T>>,
|
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
|
||||||
de: Peri<'d, impl DePin<T>>,
|
de: Peri<'d, if_afio!(impl DePin<T, A>)>,
|
||||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
tx_buffer: &'d mut [u8],
|
tx_buffer: &'d mut [u8],
|
||||||
rx_buffer: &'d mut [u8],
|
rx_buffer: &'d mut [u8],
|
||||||
@ -340,9 +340,9 @@ impl<'d> BufferedUart<'d> {
|
|||||||
/// Apart from this, the communication protocol is similar to normal USART mode. Any conflict
|
/// Apart from this, the communication protocol is similar to normal USART mode. Any conflict
|
||||||
/// on the line must be managed by software (for instance by using a centralized arbiter).
|
/// on the line must be managed by software (for instance by using a centralized arbiter).
|
||||||
#[doc(alias("HDSEL"))]
|
#[doc(alias("HDSEL"))]
|
||||||
pub fn new_half_duplex<T: Instance>(
|
pub fn new_half_duplex<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
tx: Peri<'d, impl TxPin<T>>,
|
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
|
||||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
tx_buffer: &'d mut [u8],
|
tx_buffer: &'d mut [u8],
|
||||||
rx_buffer: &'d mut [u8],
|
rx_buffer: &'d mut [u8],
|
||||||
@ -379,9 +379,9 @@ impl<'d> BufferedUart<'d> {
|
|||||||
/// on the line must be managed by software (for instance by using a centralized arbiter).
|
/// on the line must be managed by software (for instance by using a centralized arbiter).
|
||||||
#[cfg(not(any(usart_v1, usart_v2)))]
|
#[cfg(not(any(usart_v1, usart_v2)))]
|
||||||
#[doc(alias("HDSEL"))]
|
#[doc(alias("HDSEL"))]
|
||||||
pub fn new_half_duplex_on_rx<T: Instance>(
|
pub fn new_half_duplex_on_rx<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
rx: Peri<'d, impl RxPin<T>>,
|
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
|
||||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
tx_buffer: &'d mut [u8],
|
tx_buffer: &'d mut [u8],
|
||||||
rx_buffer: &'d mut [u8],
|
rx_buffer: &'d mut [u8],
|
||||||
|
@ -429,9 +429,9 @@ impl<'d, M: Mode> SetConfig for UartRx<'d, M> {
|
|||||||
|
|
||||||
impl<'d> UartTx<'d, Async> {
|
impl<'d> UartTx<'d, Async> {
|
||||||
/// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power.
|
/// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power.
|
||||||
pub fn new<T: Instance>(
|
pub fn new<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
tx: Peri<'d, impl TxPin<T>>,
|
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
|
||||||
tx_dma: Peri<'d, impl TxDma<T>>,
|
tx_dma: Peri<'d, impl TxDma<T>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Result<Self, ConfigError> {
|
) -> Result<Self, ConfigError> {
|
||||||
@ -439,10 +439,10 @@ impl<'d> UartTx<'d, Async> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new tx-only UART with a clear-to-send pin
|
/// Create a new tx-only UART with a clear-to-send pin
|
||||||
pub fn new_with_cts<T: Instance>(
|
pub fn new_with_cts<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
tx: Peri<'d, impl TxPin<T>>,
|
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
|
||||||
cts: Peri<'d, impl CtsPin<T>>,
|
cts: Peri<'d, if_afio!(impl CtsPin<T, A>)>,
|
||||||
tx_dma: Peri<'d, impl TxDma<T>>,
|
tx_dma: Peri<'d, impl TxDma<T>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Result<Self, ConfigError> {
|
) -> Result<Self, ConfigError> {
|
||||||
@ -482,19 +482,19 @@ impl<'d> UartTx<'d, Blocking> {
|
|||||||
/// Create a new blocking tx-only UART with no hardware flow control.
|
/// Create a new blocking tx-only UART with no hardware flow control.
|
||||||
///
|
///
|
||||||
/// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power.
|
/// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power.
|
||||||
pub fn new_blocking<T: Instance>(
|
pub fn new_blocking<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
tx: Peri<'d, impl TxPin<T>>,
|
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Result<Self, ConfigError> {
|
) -> Result<Self, ConfigError> {
|
||||||
Self::new_inner(peri, new_pin!(tx, config.tx_af()), None, None, config)
|
Self::new_inner(peri, new_pin!(tx, config.tx_af()), None, None, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new blocking tx-only UART with a clear-to-send pin
|
/// Create a new blocking tx-only UART with a clear-to-send pin
|
||||||
pub fn new_blocking_with_cts<T: Instance>(
|
pub fn new_blocking_with_cts<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
tx: Peri<'d, impl TxPin<T>>,
|
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
|
||||||
cts: Peri<'d, impl CtsPin<T>>,
|
cts: Peri<'d, if_afio!(impl CtsPin<T, A>)>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Result<Self, ConfigError> {
|
) -> Result<Self, ConfigError> {
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
@ -662,10 +662,10 @@ impl<'d> UartRx<'d, Async> {
|
|||||||
/// Create a new rx-only UART with no hardware flow control.
|
/// Create a new rx-only UART with no hardware flow control.
|
||||||
///
|
///
|
||||||
/// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power.
|
/// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power.
|
||||||
pub fn new<T: Instance>(
|
pub fn new<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
rx: Peri<'d, impl RxPin<T>>,
|
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
|
||||||
rx_dma: Peri<'d, impl RxDma<T>>,
|
rx_dma: Peri<'d, impl RxDma<T>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Result<Self, ConfigError> {
|
) -> Result<Self, ConfigError> {
|
||||||
@ -673,11 +673,11 @@ impl<'d> UartRx<'d, Async> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new rx-only UART with a request-to-send pin
|
/// Create a new rx-only UART with a request-to-send pin
|
||||||
pub fn new_with_rts<T: Instance>(
|
pub fn new_with_rts<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
rx: Peri<'d, impl RxPin<T>>,
|
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
|
||||||
rts: Peri<'d, impl RtsPin<T>>,
|
rts: Peri<'d, if_afio!(impl RtsPin<T, A>)>,
|
||||||
rx_dma: Peri<'d, impl RxDma<T>>,
|
rx_dma: Peri<'d, impl RxDma<T>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Result<Self, ConfigError> {
|
) -> Result<Self, ConfigError> {
|
||||||
@ -913,19 +913,19 @@ impl<'d> UartRx<'d, Blocking> {
|
|||||||
/// Create a new rx-only UART with no hardware flow control.
|
/// Create a new rx-only UART with no hardware flow control.
|
||||||
///
|
///
|
||||||
/// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power.
|
/// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power.
|
||||||
pub fn new_blocking<T: Instance>(
|
pub fn new_blocking<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
rx: Peri<'d, impl RxPin<T>>,
|
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Result<Self, ConfigError> {
|
) -> Result<Self, ConfigError> {
|
||||||
Self::new_inner(peri, new_pin!(rx, config.rx_af()), None, None, config)
|
Self::new_inner(peri, new_pin!(rx, config.rx_af()), None, None, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new rx-only UART with a request-to-send pin
|
/// Create a new rx-only UART with a request-to-send pin
|
||||||
pub fn new_blocking_with_rts<T: Instance>(
|
pub fn new_blocking_with_rts<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
rx: Peri<'d, impl RxPin<T>>,
|
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
|
||||||
rts: Peri<'d, impl RtsPin<T>>,
|
rts: Peri<'d, if_afio!(impl RtsPin<T, A>)>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Result<Self, ConfigError> {
|
) -> Result<Self, ConfigError> {
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
@ -1109,10 +1109,10 @@ fn drop_tx_rx(info: &Info, state: &State) {
|
|||||||
|
|
||||||
impl<'d> Uart<'d, Async> {
|
impl<'d> Uart<'d, Async> {
|
||||||
/// Create a new bidirectional UART
|
/// Create a new bidirectional UART
|
||||||
pub fn new<T: Instance>(
|
pub fn new<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
rx: Peri<'d, impl RxPin<T>>,
|
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
|
||||||
tx: Peri<'d, impl TxPin<T>>,
|
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
|
||||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
tx_dma: Peri<'d, impl TxDma<T>>,
|
tx_dma: Peri<'d, impl TxDma<T>>,
|
||||||
rx_dma: Peri<'d, impl RxDma<T>>,
|
rx_dma: Peri<'d, impl RxDma<T>>,
|
||||||
@ -1132,13 +1132,13 @@ impl<'d> Uart<'d, Async> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new bidirectional UART with request-to-send and clear-to-send pins
|
/// Create a new bidirectional UART with request-to-send and clear-to-send pins
|
||||||
pub fn new_with_rtscts<T: Instance>(
|
pub fn new_with_rtscts<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
rx: Peri<'d, impl RxPin<T>>,
|
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
|
||||||
tx: Peri<'d, impl TxPin<T>>,
|
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
|
||||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
rts: Peri<'d, impl RtsPin<T>>,
|
rts: Peri<'d, if_afio!(impl RtsPin<T, A>)>,
|
||||||
cts: Peri<'d, impl CtsPin<T>>,
|
cts: Peri<'d, if_afio!(impl CtsPin<T, A>)>,
|
||||||
tx_dma: Peri<'d, impl TxDma<T>>,
|
tx_dma: Peri<'d, impl TxDma<T>>,
|
||||||
rx_dma: Peri<'d, impl RxDma<T>>,
|
rx_dma: Peri<'d, impl RxDma<T>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
@ -1158,12 +1158,12 @@ impl<'d> Uart<'d, Async> {
|
|||||||
|
|
||||||
#[cfg(not(any(usart_v1, usart_v2)))]
|
#[cfg(not(any(usart_v1, usart_v2)))]
|
||||||
/// Create a new bidirectional UART with a driver-enable pin
|
/// Create a new bidirectional UART with a driver-enable pin
|
||||||
pub fn new_with_de<T: Instance>(
|
pub fn new_with_de<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
rx: Peri<'d, impl RxPin<T>>,
|
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
|
||||||
tx: Peri<'d, impl TxPin<T>>,
|
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
|
||||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
de: Peri<'d, impl DePin<T>>,
|
de: Peri<'d, if_afio!(impl DePin<T, A>)>,
|
||||||
tx_dma: Peri<'d, impl TxDma<T>>,
|
tx_dma: Peri<'d, impl TxDma<T>>,
|
||||||
rx_dma: Peri<'d, impl RxDma<T>>,
|
rx_dma: Peri<'d, impl RxDma<T>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
@ -1193,9 +1193,9 @@ impl<'d> Uart<'d, Async> {
|
|||||||
/// Apart from this, the communication protocol is similar to normal USART mode. Any conflict
|
/// Apart from this, the communication protocol is similar to normal USART mode. Any conflict
|
||||||
/// on the line must be managed by software (for instance by using a centralized arbiter).
|
/// on the line must be managed by software (for instance by using a centralized arbiter).
|
||||||
#[doc(alias("HDSEL"))]
|
#[doc(alias("HDSEL"))]
|
||||||
pub fn new_half_duplex<T: Instance>(
|
pub fn new_half_duplex<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
tx: Peri<'d, impl TxPin<T>>,
|
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
|
||||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
tx_dma: Peri<'d, impl TxDma<T>>,
|
tx_dma: Peri<'d, impl TxDma<T>>,
|
||||||
rx_dma: Peri<'d, impl RxDma<T>>,
|
rx_dma: Peri<'d, impl RxDma<T>>,
|
||||||
@ -1232,9 +1232,9 @@ impl<'d> Uart<'d, Async> {
|
|||||||
/// on the line must be managed by software (for instance by using a centralized arbiter).
|
/// on the line must be managed by software (for instance by using a centralized arbiter).
|
||||||
#[cfg(not(any(usart_v1, usart_v2)))]
|
#[cfg(not(any(usart_v1, usart_v2)))]
|
||||||
#[doc(alias("HDSEL"))]
|
#[doc(alias("HDSEL"))]
|
||||||
pub fn new_half_duplex_on_rx<T: Instance>(
|
pub fn new_half_duplex_on_rx<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
rx: Peri<'d, impl RxPin<T>>,
|
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
|
||||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
tx_dma: Peri<'d, impl TxDma<T>>,
|
tx_dma: Peri<'d, impl TxDma<T>>,
|
||||||
rx_dma: Peri<'d, impl RxDma<T>>,
|
rx_dma: Peri<'d, impl RxDma<T>>,
|
||||||
@ -1280,10 +1280,10 @@ impl<'d> Uart<'d, Async> {
|
|||||||
|
|
||||||
impl<'d> Uart<'d, Blocking> {
|
impl<'d> Uart<'d, Blocking> {
|
||||||
/// Create a new blocking bidirectional UART.
|
/// Create a new blocking bidirectional UART.
|
||||||
pub fn new_blocking<T: Instance>(
|
pub fn new_blocking<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
rx: Peri<'d, impl RxPin<T>>,
|
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
|
||||||
tx: Peri<'d, impl TxPin<T>>,
|
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Result<Self, ConfigError> {
|
) -> Result<Self, ConfigError> {
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
@ -1300,12 +1300,12 @@ impl<'d> Uart<'d, Blocking> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new bidirectional UART with request-to-send and clear-to-send pins
|
/// Create a new bidirectional UART with request-to-send and clear-to-send pins
|
||||||
pub fn new_blocking_with_rtscts<T: Instance>(
|
pub fn new_blocking_with_rtscts<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
rx: Peri<'d, impl RxPin<T>>,
|
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
|
||||||
tx: Peri<'d, impl TxPin<T>>,
|
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
|
||||||
rts: Peri<'d, impl RtsPin<T>>,
|
rts: Peri<'d, if_afio!(impl RtsPin<T, A>)>,
|
||||||
cts: Peri<'d, impl CtsPin<T>>,
|
cts: Peri<'d, if_afio!(impl CtsPin<T, A>)>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Result<Self, ConfigError> {
|
) -> Result<Self, ConfigError> {
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
@ -1323,11 +1323,11 @@ impl<'d> Uart<'d, Blocking> {
|
|||||||
|
|
||||||
#[cfg(not(any(usart_v1, usart_v2)))]
|
#[cfg(not(any(usart_v1, usart_v2)))]
|
||||||
/// Create a new bidirectional UART with a driver-enable pin
|
/// Create a new bidirectional UART with a driver-enable pin
|
||||||
pub fn new_blocking_with_de<T: Instance>(
|
pub fn new_blocking_with_de<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
rx: Peri<'d, impl RxPin<T>>,
|
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
|
||||||
tx: Peri<'d, impl TxPin<T>>,
|
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
|
||||||
de: Peri<'d, impl DePin<T>>,
|
de: Peri<'d, if_afio!(impl DePin<T, A>)>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Result<Self, ConfigError> {
|
) -> Result<Self, ConfigError> {
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
@ -1354,9 +1354,9 @@ impl<'d> Uart<'d, Blocking> {
|
|||||||
/// Apart from this, the communication protocol is similar to normal USART mode. Any conflict
|
/// Apart from this, the communication protocol is similar to normal USART mode. Any conflict
|
||||||
/// on the line must be managed by software (for instance by using a centralized arbiter).
|
/// on the line must be managed by software (for instance by using a centralized arbiter).
|
||||||
#[doc(alias("HDSEL"))]
|
#[doc(alias("HDSEL"))]
|
||||||
pub fn new_blocking_half_duplex<T: Instance>(
|
pub fn new_blocking_half_duplex<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
tx: Peri<'d, impl TxPin<T>>,
|
tx: Peri<'d, if_afio!(impl TxPin<T, A>)>,
|
||||||
mut config: Config,
|
mut config: Config,
|
||||||
readback: HalfDuplexReadback,
|
readback: HalfDuplexReadback,
|
||||||
) -> Result<Self, ConfigError> {
|
) -> Result<Self, ConfigError> {
|
||||||
@ -1390,9 +1390,9 @@ impl<'d> Uart<'d, Blocking> {
|
|||||||
/// on the line must be managed by software (for instance by using a centralized arbiter).
|
/// on the line must be managed by software (for instance by using a centralized arbiter).
|
||||||
#[cfg(not(any(usart_v1, usart_v2)))]
|
#[cfg(not(any(usart_v1, usart_v2)))]
|
||||||
#[doc(alias("HDSEL"))]
|
#[doc(alias("HDSEL"))]
|
||||||
pub fn new_blocking_half_duplex_on_rx<T: Instance>(
|
pub fn new_blocking_half_duplex_on_rx<T: Instance, #[cfg(afio)] A>(
|
||||||
peri: Peri<'d, T>,
|
peri: Peri<'d, T>,
|
||||||
rx: Peri<'d, impl RxPin<T>>,
|
rx: Peri<'d, if_afio!(impl RxPin<T, A>)>,
|
||||||
mut config: Config,
|
mut config: Config,
|
||||||
readback: HalfDuplexReadback,
|
readback: HalfDuplexReadback,
|
||||||
) -> Result<Self, ConfigError> {
|
) -> Result<Self, ConfigError> {
|
||||||
@ -2055,12 +2055,12 @@ pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
|
|||||||
type Interrupt: interrupt::typelevel::Interrupt;
|
type Interrupt: interrupt::typelevel::Interrupt;
|
||||||
}
|
}
|
||||||
|
|
||||||
pin_trait!(RxPin, Instance);
|
pin_trait!(RxPin, Instance, @A);
|
||||||
pin_trait!(TxPin, Instance);
|
pin_trait!(TxPin, Instance, @A);
|
||||||
pin_trait!(CtsPin, Instance);
|
pin_trait!(CtsPin, Instance, @A);
|
||||||
pin_trait!(RtsPin, Instance);
|
pin_trait!(RtsPin, Instance, @A);
|
||||||
pin_trait!(CkPin, Instance);
|
pin_trait!(CkPin, Instance, @A);
|
||||||
pin_trait!(DePin, Instance);
|
pin_trait!(DePin, Instance, @A);
|
||||||
|
|
||||||
dma_trait!(TxDma, Instance);
|
dma_trait!(TxDma, Instance);
|
||||||
dma_trait!(RxDma, Instance);
|
dma_trait!(RxDma, Instance);
|
||||||
|
@ -34,7 +34,7 @@ macro_rules! config_ulpi_pins {
|
|||||||
($($pin:ident),*) => {
|
($($pin:ident),*) => {
|
||||||
critical_section::with(|_| {
|
critical_section::with(|_| {
|
||||||
$(
|
$(
|
||||||
$pin.set_as_af($pin.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
set_as_af!($pin, AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
||||||
)*
|
)*
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@ -68,8 +68,8 @@ impl<'d, T: Instance> Driver<'d, T> {
|
|||||||
ep_out_buffer: &'d mut [u8],
|
ep_out_buffer: &'d mut [u8],
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
dp.set_as_af(dp.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
set_as_af!(dp, AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
||||||
dm.set_as_af(dm.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
set_as_af!(dm, AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
||||||
|
|
||||||
let regs = T::regs();
|
let regs = T::regs();
|
||||||
|
|
||||||
@ -107,8 +107,8 @@ impl<'d, T: Instance> Driver<'d, T> {
|
|||||||
// For STM32U5 High speed pins need to be left in analog mode
|
// For STM32U5 High speed pins need to be left in analog mode
|
||||||
#[cfg(not(any(all(stm32u5, peri_usb_otg_hs), all(stm32wba, peri_usb_otg_hs))))]
|
#[cfg(not(any(all(stm32u5, peri_usb_otg_hs), all(stm32wba, peri_usb_otg_hs))))]
|
||||||
{
|
{
|
||||||
_dp.set_as_af(_dp.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
set_as_af!(_dp, AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
||||||
_dm.set_as_af(_dm.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
set_as_af!(_dm, AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
||||||
}
|
}
|
||||||
|
|
||||||
let instance = OtgInstance {
|
let instance = OtgInstance {
|
||||||
|
@ -298,7 +298,7 @@ impl<'d, T: Instance> Driver<'d, T> {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
{
|
{
|
||||||
use crate::gpio::{AfType, OutputType, Speed};
|
use crate::gpio::{AfType, OutputType, Speed};
|
||||||
sof.set_as_af(sof.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
set_as_af!(sof, AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::new(_usb, _irq, dp, dm)
|
Self::new(_usb, _irq, dp, dm)
|
||||||
@ -329,8 +329,8 @@ impl<'d, T: Instance> Driver<'d, T> {
|
|||||||
#[cfg(not(stm32l1))]
|
#[cfg(not(stm32l1))]
|
||||||
{
|
{
|
||||||
use crate::gpio::{AfType, OutputType, Speed};
|
use crate::gpio::{AfType, OutputType, Speed};
|
||||||
dp.set_as_af(dp.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
set_as_af!(dp, AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
||||||
dm.set_as_af(dm.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
set_as_af!(dm, AfType::output(OutputType::PushPull, Speed::VeryHigh));
|
||||||
}
|
}
|
||||||
#[cfg(stm32l1)]
|
#[cfg(stm32l1)]
|
||||||
let _ = (dp, dm); // suppress "unused" warnings.
|
let _ = (dp, dm); // suppress "unused" warnings.
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_stm32::gpio::{Level, Output, Pull, Speed};
|
use embassy_stm32::gpio::{AfioRemap, Level, Output, Pull, Speed};
|
||||||
use embassy_stm32::time::khz;
|
use embassy_stm32::time::khz;
|
||||||
use embassy_stm32::timer::input_capture::{CapturePin, InputCapture};
|
use embassy_stm32::timer::input_capture::{CapturePin, InputCapture};
|
||||||
use embassy_stm32::timer::{self, Channel};
|
use embassy_stm32::timer::{self, Channel};
|
||||||
@ -40,7 +40,8 @@ async fn main(spawner: Spawner) {
|
|||||||
spawner.spawn(unwrap!(blinky(p.PC13)));
|
spawner.spawn(unwrap!(blinky(p.PC13)));
|
||||||
|
|
||||||
let ch3 = CapturePin::new(p.PA2, Pull::None);
|
let ch3 = CapturePin::new(p.PA2, Pull::None);
|
||||||
let mut ic = InputCapture::new(p.TIM2, None, None, Some(ch3), None, Irqs, khz(1000), Default::default());
|
let mut ic =
|
||||||
|
InputCapture::new::<AfioRemap<0>>(p.TIM2, None, None, Some(ch3), None, Irqs, khz(1000), Default::default());
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
info!("wait for rising edge");
|
info!("wait for rising edge");
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_stm32::gpio::{Level, Output, Pull, Speed};
|
use embassy_stm32::gpio::{AfioRemap, Level, Output, Pull, Speed};
|
||||||
use embassy_stm32::time::khz;
|
use embassy_stm32::time::khz;
|
||||||
use embassy_stm32::timer::pwm_input::PwmInput;
|
use embassy_stm32::timer::pwm_input::PwmInput;
|
||||||
use embassy_stm32::{bind_interrupts, peripherals, timer, Peri};
|
use embassy_stm32::{bind_interrupts, peripherals, timer, Peri};
|
||||||
@ -38,7 +38,7 @@ async fn main(spawner: Spawner) {
|
|||||||
|
|
||||||
spawner.spawn(unwrap!(blinky(p.PC13)));
|
spawner.spawn(unwrap!(blinky(p.PC13)));
|
||||||
|
|
||||||
let mut pwm_input = PwmInput::new_ch1(p.TIM2, p.PA0, Pull::None, khz(10));
|
let mut pwm_input = PwmInput::new_ch1::<AfioRemap<0>>(p.TIM2, p.PA0, Pull::None, khz(10));
|
||||||
pwm_input.enable();
|
pwm_input.enable();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -9,7 +9,9 @@ publish = false
|
|||||||
[features]
|
[features]
|
||||||
stm32c031c6 = ["embassy-stm32/stm32c031c6", "cm0", "not-gpdma"]
|
stm32c031c6 = ["embassy-stm32/stm32c031c6", "cm0", "not-gpdma"]
|
||||||
stm32c071rb = ["embassy-stm32/stm32c071rb", "cm0", "not-gpdma"]
|
stm32c071rb = ["embassy-stm32/stm32c071rb", "cm0", "not-gpdma"]
|
||||||
stm32f103c8 = ["embassy-stm32/stm32f103c8", "spi-v1", "not-gpdma"]
|
stm32f100rd = ["embassy-stm32/stm32f100rd", "spi-v1", "not-gpdma", "afio", "afio-value-line"]
|
||||||
|
stm32f103c8 = ["embassy-stm32/stm32f103c8", "spi-v1", "not-gpdma", "afio"]
|
||||||
|
stm32f107vc = ["embassy-stm32/stm32f107vc", "spi-v1", "not-gpdma", "afio", "afio-connectivity-line"]
|
||||||
stm32f207zg = ["embassy-stm32/stm32f207zg", "spi-v1", "chrono", "not-gpdma", "eth", "rng"]
|
stm32f207zg = ["embassy-stm32/stm32f207zg", "spi-v1", "chrono", "not-gpdma", "eth", "rng"]
|
||||||
stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"]
|
stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"]
|
||||||
stm32f429zi = ["embassy-stm32/stm32f429zi", "spi-v1", "chrono", "eth", "stop", "can", "not-gpdma", "dac", "rng"]
|
stm32f429zi = ["embassy-stm32/stm32f429zi", "spi-v1", "chrono", "eth", "stop", "can", "not-gpdma", "dac", "rng"]
|
||||||
@ -59,6 +61,9 @@ cordic = ["dep:num-traits"]
|
|||||||
dual-bank = ["embassy-stm32/dual-bank"]
|
dual-bank = ["embassy-stm32/dual-bank"]
|
||||||
single-bank = ["embassy-stm32/single-bank"]
|
single-bank = ["embassy-stm32/single-bank"]
|
||||||
eeprom = []
|
eeprom = []
|
||||||
|
afio = []
|
||||||
|
afio-connectivity-line = []
|
||||||
|
afio-value-line = []
|
||||||
|
|
||||||
cm0 = ["portable-atomic/unsafe-assume-single-core"]
|
cm0 = ["portable-atomic/unsafe-assume-single-core"]
|
||||||
|
|
||||||
@ -98,6 +103,11 @@ num-traits = { version="0.2", default-features = false,features = ["libm"], opti
|
|||||||
|
|
||||||
# BEGIN TESTS
|
# BEGIN TESTS
|
||||||
# Generated by gen_test.py. DO NOT EDIT.
|
# Generated by gen_test.py. DO NOT EDIT.
|
||||||
|
[[bin]]
|
||||||
|
name = "afio"
|
||||||
|
path = "src/bin/afio.rs"
|
||||||
|
required-features = [ "afio",]
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "can"
|
name = "can"
|
||||||
path = "src/bin/can.rs"
|
path = "src/bin/can.rs"
|
||||||
|
1156
tests/stm32/src/bin/afio.rs
Normal file
1156
tests/stm32/src/bin/afio.rs
Normal file
File diff suppressed because it is too large
Load Diff
@ -103,7 +103,7 @@ define_peris!(
|
|||||||
SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2,
|
SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2,
|
||||||
@irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;},
|
@irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;},
|
||||||
);
|
);
|
||||||
#[cfg(feature = "stm32f103c8")]
|
#[cfg(any(feature = "stm32f100rd", feature = "stm32f103c8", feature = "stm32f107vc"))]
|
||||||
define_peris!(
|
define_peris!(
|
||||||
UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA1_CH4, UART_RX_DMA = DMA1_CH5,
|
UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA1_CH4, UART_RX_DMA = DMA1_CH5,
|
||||||
SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2,
|
SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user