Replace embassy::io with embedded_io.
This commit is contained in:
@ -57,12 +57,13 @@ critical-section = "0.2.5"
|
||||
bare-metal = "1.0.0"
|
||||
atomic-polyfill = "0.1.5"
|
||||
stm32-metapac = { version = "0.1.0", path = "../stm32-metapac", features = ["rt"] }
|
||||
vcell = { version = "0.1.3", optional = true }
|
||||
vcell = "0.1.3"
|
||||
bxcan = "0.6.2"
|
||||
nb = "1.0.0"
|
||||
stm32-fmc = "0.2.4"
|
||||
seq-macro = "0.2.2"
|
||||
cfg-if = "1.0.0"
|
||||
embedded-io = { version = "0.2.0", features = ["async"], optional = true }
|
||||
|
||||
[build-dependencies]
|
||||
proc-macro2 = "1.0.36"
|
||||
@ -70,8 +71,9 @@ quote = "1.0.15"
|
||||
stm32-metapac = { version = "0.1.0", path = "../stm32-metapac", default-features = false, features = ["metadata"]}
|
||||
|
||||
[features]
|
||||
defmt = ["dep:defmt", "embassy/defmt", "embedded-io?/defmt" ]
|
||||
sdmmc-rs = ["embedded-sdmmc"]
|
||||
net = ["embassy-net", "vcell"]
|
||||
net = ["embassy-net" ]
|
||||
memory-x = ["stm32-metapac/memory-x"]
|
||||
subghz = []
|
||||
exti = []
|
||||
@ -88,7 +90,7 @@ time-driver-tim12 = ["_time-driver"]
|
||||
time-driver-tim15 = ["_time-driver"]
|
||||
|
||||
# Enable nightly-only features
|
||||
nightly = ["embassy/nightly", "embedded-hal-1", "embedded-hal-async", "embedded-storage-async"]
|
||||
nightly = ["embassy/nightly", "embassy-net?/nightly", "embedded-hal-1", "embedded-hal-async", "embedded-storage-async", "dep:embedded-io"]
|
||||
|
||||
# Reexport stm32-metapac at `embassy_stm32::pac`.
|
||||
# This is unstable because semver-minor (non-breaking) releases of embassy-stm32 may major-bump (breaking) the stm32-metapac version.
|
||||
|
@ -244,200 +244,200 @@ fn main() {
|
||||
|
||||
#[rustfmt::skip]
|
||||
let signals: HashMap<_, _> = [
|
||||
// (kind, signal) => (trait, cfgs)
|
||||
(("usart", "TX"), (quote!(crate::usart::TxPin), quote!())),
|
||||
(("usart", "RX"), (quote!(crate::usart::RxPin), quote!())),
|
||||
(("usart", "CTS"), (quote!(crate::usart::CtsPin), quote!())),
|
||||
(("usart", "RTS"), (quote!(crate::usart::RtsPin), quote!())),
|
||||
(("usart", "CK"), (quote!(crate::usart::CkPin), quote!())),
|
||||
(("usart", "TX"), (quote!(crate::usart::TxPin), quote!())),
|
||||
(("usart", "RX"), (quote!(crate::usart::RxPin), quote!())),
|
||||
(("usart", "CTS"), (quote!(crate::usart::CtsPin), quote!())),
|
||||
(("usart", "RTS"), (quote!(crate::usart::RtsPin), quote!())),
|
||||
(("usart", "CK"), (quote!(crate::usart::CkPin), quote!())),
|
||||
(("spi", "SCK"), (quote!(crate::spi::SckPin), quote!())),
|
||||
(("spi", "MOSI"), (quote!(crate::spi::MosiPin), quote!())),
|
||||
(("spi", "MISO"), (quote!(crate::spi::MisoPin), quote!())),
|
||||
(("i2c", "SDA"), (quote!(crate::i2c::SdaPin), quote!())),
|
||||
(("i2c", "SCL"), (quote!(crate::i2c::SclPin), quote!())),
|
||||
(("rcc", "MCO_1"), (quote!(crate::rcc::McoPin), quote!())),
|
||||
(("rcc", "MCO_2"), (quote!(crate::rcc::McoPin), quote!())),
|
||||
(("dcmi", "D0"), (quote!(crate::dcmi::D0Pin), quote!())),
|
||||
(("dcmi", "D1"), (quote!(crate::dcmi::D1Pin), quote!())),
|
||||
(("dcmi", "D2"), (quote!(crate::dcmi::D2Pin), quote!())),
|
||||
(("dcmi", "D3"), (quote!(crate::dcmi::D3Pin), quote!())),
|
||||
(("dcmi", "D4"), (quote!(crate::dcmi::D4Pin), quote!())),
|
||||
(("dcmi", "D5"), (quote!(crate::dcmi::D5Pin), quote!())),
|
||||
(("dcmi", "D6"), (quote!(crate::dcmi::D6Pin), quote!())),
|
||||
(("dcmi", "D7"), (quote!(crate::dcmi::D7Pin), quote!())),
|
||||
(("dcmi", "D8"), (quote!(crate::dcmi::D8Pin), quote!())),
|
||||
(("dcmi", "D9"), (quote!(crate::dcmi::D9Pin), quote!())),
|
||||
(("dcmi", "D10"), (quote!(crate::dcmi::D10Pin), quote!())),
|
||||
(("dcmi", "D11"), (quote!(crate::dcmi::D11Pin), quote!())),
|
||||
(("dcmi", "D12"), (quote!(crate::dcmi::D12Pin), quote!())),
|
||||
(("dcmi", "D13"), (quote!(crate::dcmi::D13Pin), quote!())),
|
||||
(("dcmi", "HSYNC"), (quote!(crate::dcmi::HSyncPin), quote!())),
|
||||
(("dcmi", "VSYNC"), (quote!(crate::dcmi::VSyncPin), quote!())),
|
||||
(("dcmi", "PIXCLK"), (quote!(crate::dcmi::PixClkPin), quote!())),
|
||||
(("otgfs", "DP"), (quote!(crate::usb_otg::DpPin), quote!())),
|
||||
(("otgfs", "DM"), (quote!(crate::usb_otg::DmPin), quote!())),
|
||||
(("otghs", "DP"), (quote!(crate::usb_otg::DpPin), quote!())),
|
||||
(("otghs", "DM"), (quote!(crate::usb_otg::DmPin), quote!())),
|
||||
(("otghs", "ULPI_CK"), (quote!(crate::usb_otg::UlpiClkPin), quote!())),
|
||||
(("otghs", "ULPI_DIR"), (quote!(crate::usb_otg::UlpiDirPin), quote!())),
|
||||
(("otghs", "ULPI_NXT"), (quote!(crate::usb_otg::UlpiNxtPin), quote!())),
|
||||
(("otghs", "ULPI_STP"), (quote!(crate::usb_otg::UlpiStpPin), quote!())),
|
||||
(("otghs", "ULPI_D0"), (quote!(crate::usb_otg::UlpiD0Pin), quote!())),
|
||||
(("otghs", "ULPI_D1"), (quote!(crate::usb_otg::UlpiD1Pin), quote!())),
|
||||
(("otghs", "ULPI_D2"), (quote!(crate::usb_otg::UlpiD2Pin), quote!())),
|
||||
(("otghs", "ULPI_D3"), (quote!(crate::usb_otg::UlpiD3Pin), quote!())),
|
||||
(("otghs", "ULPI_D4"), (quote!(crate::usb_otg::UlpiD4Pin), quote!())),
|
||||
(("otghs", "ULPI_D5"), (quote!(crate::usb_otg::UlpiD5Pin), quote!())),
|
||||
(("otghs", "ULPI_D6"), (quote!(crate::usb_otg::UlpiD6Pin), quote!())),
|
||||
(("otghs", "ULPI_D7"), (quote!(crate::usb_otg::UlpiD7Pin), quote!())),
|
||||
(("can", "TX"), (quote!(crate::can::TxPin), quote!())),
|
||||
(("can", "RX"), (quote!(crate::can::RxPin), quote!())),
|
||||
(("eth", "REF_CLK"), (quote!(crate::eth::RefClkPin), quote!(#[cfg(feature="net")]))),
|
||||
(("eth", "MDIO"), (quote!(crate::eth::MDIOPin), quote!(#[cfg(feature="net")]))),
|
||||
(("eth", "MDC"), (quote!(crate::eth::MDCPin), quote!(#[cfg(feature="net")]))),
|
||||
(("eth", "CRS_DV"), (quote!(crate::eth::CRSPin), quote!(#[cfg(feature="net")]))),
|
||||
(("eth", "RXD0"), (quote!(crate::eth::RXD0Pin), quote!(#[cfg(feature="net")]))),
|
||||
(("eth", "RXD1"), (quote!(crate::eth::RXD1Pin), quote!(#[cfg(feature="net")]))),
|
||||
(("eth", "TXD0"), (quote!(crate::eth::TXD0Pin), quote!(#[cfg(feature="net")]))),
|
||||
(("eth", "TXD1"), (quote!(crate::eth::TXD1Pin), quote!(#[cfg(feature="net")]))),
|
||||
(("eth", "TX_EN"), (quote!(crate::eth::TXEnPin), quote!(#[cfg(feature="net")]))),
|
||||
(("fmc", "A0"), (quote!(crate::fmc::A0Pin), quote!())),
|
||||
(("fmc", "A1"), (quote!(crate::fmc::A1Pin), quote!())),
|
||||
(("fmc", "A2"), (quote!(crate::fmc::A2Pin), quote!())),
|
||||
(("fmc", "A3"), (quote!(crate::fmc::A3Pin), quote!())),
|
||||
(("fmc", "A4"), (quote!(crate::fmc::A4Pin), quote!())),
|
||||
(("fmc", "A5"), (quote!(crate::fmc::A5Pin), quote!())),
|
||||
(("fmc", "A6"), (quote!(crate::fmc::A6Pin), quote!())),
|
||||
(("fmc", "A7"), (quote!(crate::fmc::A7Pin), quote!())),
|
||||
(("fmc", "A8"), (quote!(crate::fmc::A8Pin), quote!())),
|
||||
(("fmc", "A9"), (quote!(crate::fmc::A9Pin), quote!())),
|
||||
(("fmc", "A10"), (quote!(crate::fmc::A10Pin), quote!())),
|
||||
(("fmc", "A11"), (quote!(crate::fmc::A11Pin), quote!())),
|
||||
(("fmc", "A12"), (quote!(crate::fmc::A12Pin), quote!())),
|
||||
(("fmc", "A13"), (quote!(crate::fmc::A13Pin), quote!())),
|
||||
(("fmc", "A14"), (quote!(crate::fmc::A14Pin), quote!())),
|
||||
(("fmc", "A15"), (quote!(crate::fmc::A15Pin), quote!())),
|
||||
(("fmc", "A16"), (quote!(crate::fmc::A16Pin), quote!())),
|
||||
(("fmc", "A17"), (quote!(crate::fmc::A17Pin), quote!())),
|
||||
(("fmc", "A18"), (quote!(crate::fmc::A18Pin), quote!())),
|
||||
(("fmc", "A19"), (quote!(crate::fmc::A19Pin), quote!())),
|
||||
(("fmc", "A20"), (quote!(crate::fmc::A20Pin), quote!())),
|
||||
(("fmc", "A21"), (quote!(crate::fmc::A21Pin), quote!())),
|
||||
(("fmc", "A22"), (quote!(crate::fmc::A22Pin), quote!())),
|
||||
(("fmc", "A23"), (quote!(crate::fmc::A23Pin), quote!())),
|
||||
(("fmc", "A24"), (quote!(crate::fmc::A24Pin), quote!())),
|
||||
(("fmc", "A25"), (quote!(crate::fmc::A25Pin), quote!())),
|
||||
(("fmc", "D0"), (quote!(crate::fmc::D0Pin), quote!())),
|
||||
(("fmc", "D1"), (quote!(crate::fmc::D1Pin), quote!())),
|
||||
(("fmc", "D2"), (quote!(crate::fmc::D2Pin), quote!())),
|
||||
(("fmc", "D3"), (quote!(crate::fmc::D3Pin), quote!())),
|
||||
(("fmc", "D4"), (quote!(crate::fmc::D4Pin), quote!())),
|
||||
(("fmc", "D5"), (quote!(crate::fmc::D5Pin), quote!())),
|
||||
(("fmc", "D6"), (quote!(crate::fmc::D6Pin), quote!())),
|
||||
(("fmc", "D7"), (quote!(crate::fmc::D7Pin), quote!())),
|
||||
(("fmc", "D8"), (quote!(crate::fmc::D8Pin), quote!())),
|
||||
(("fmc", "D9"), (quote!(crate::fmc::D9Pin), quote!())),
|
||||
(("fmc", "D10"), (quote!(crate::fmc::D10Pin), quote!())),
|
||||
(("fmc", "D11"), (quote!(crate::fmc::D11Pin), quote!())),
|
||||
(("fmc", "D12"), (quote!(crate::fmc::D12Pin), quote!())),
|
||||
(("fmc", "D13"), (quote!(crate::fmc::D13Pin), quote!())),
|
||||
(("fmc", "D14"), (quote!(crate::fmc::D14Pin), quote!())),
|
||||
(("fmc", "D15"), (quote!(crate::fmc::D15Pin), quote!())),
|
||||
(("fmc", "D16"), (quote!(crate::fmc::D16Pin), quote!())),
|
||||
(("fmc", "D17"), (quote!(crate::fmc::D17Pin), quote!())),
|
||||
(("fmc", "D18"), (quote!(crate::fmc::D18Pin), quote!())),
|
||||
(("fmc", "D19"), (quote!(crate::fmc::D19Pin), quote!())),
|
||||
(("fmc", "D20"), (quote!(crate::fmc::D20Pin), quote!())),
|
||||
(("fmc", "D21"), (quote!(crate::fmc::D21Pin), quote!())),
|
||||
(("fmc", "D22"), (quote!(crate::fmc::D22Pin), quote!())),
|
||||
(("fmc", "D23"), (quote!(crate::fmc::D23Pin), quote!())),
|
||||
(("fmc", "D24"), (quote!(crate::fmc::D24Pin), quote!())),
|
||||
(("fmc", "D25"), (quote!(crate::fmc::D25Pin), quote!())),
|
||||
(("fmc", "D26"), (quote!(crate::fmc::D26Pin), quote!())),
|
||||
(("fmc", "D27"), (quote!(crate::fmc::D27Pin), quote!())),
|
||||
(("fmc", "D28"), (quote!(crate::fmc::D28Pin), quote!())),
|
||||
(("fmc", "D29"), (quote!(crate::fmc::D29Pin), quote!())),
|
||||
(("fmc", "D30"), (quote!(crate::fmc::D30Pin), quote!())),
|
||||
(("fmc", "D31"), (quote!(crate::fmc::D31Pin), quote!())),
|
||||
(("fmc", "DA0"), (quote!(crate::fmc::DA0Pin), quote!())),
|
||||
(("fmc", "DA1"), (quote!(crate::fmc::DA1Pin), quote!())),
|
||||
(("fmc", "DA2"), (quote!(crate::fmc::DA2Pin), quote!())),
|
||||
(("fmc", "DA3"), (quote!(crate::fmc::DA3Pin), quote!())),
|
||||
(("fmc", "DA4"), (quote!(crate::fmc::DA4Pin), quote!())),
|
||||
(("fmc", "DA5"), (quote!(crate::fmc::DA5Pin), quote!())),
|
||||
(("fmc", "DA6"), (quote!(crate::fmc::DA6Pin), quote!())),
|
||||
(("fmc", "DA7"), (quote!(crate::fmc::DA7Pin), quote!())),
|
||||
(("fmc", "DA8"), (quote!(crate::fmc::DA8Pin), quote!())),
|
||||
(("fmc", "DA9"), (quote!(crate::fmc::DA9Pin), quote!())),
|
||||
(("fmc", "DA10"), (quote!(crate::fmc::DA10Pin), quote!())),
|
||||
(("fmc", "DA11"), (quote!(crate::fmc::DA11Pin), quote!())),
|
||||
(("fmc", "DA12"), (quote!(crate::fmc::DA12Pin), quote!())),
|
||||
(("fmc", "DA13"), (quote!(crate::fmc::DA13Pin), quote!())),
|
||||
(("fmc", "DA14"), (quote!(crate::fmc::DA14Pin), quote!())),
|
||||
(("fmc", "DA15"), (quote!(crate::fmc::DA15Pin), quote!())),
|
||||
(("fmc", "SDNWE"), (quote!(crate::fmc::SDNWEPin), quote!())),
|
||||
(("fmc", "SDNCAS"), (quote!(crate::fmc::SDNCASPin), quote!())),
|
||||
(("fmc", "SDNRAS"), (quote!(crate::fmc::SDNRASPin), quote!())),
|
||||
(("fmc", "SDNE0"), (quote!(crate::fmc::SDNE0Pin), quote!())),
|
||||
(("fmc", "SDNE1"), (quote!(crate::fmc::SDNE1Pin), quote!())),
|
||||
(("fmc", "SDCKE0"), (quote!(crate::fmc::SDCKE0Pin), quote!())),
|
||||
(("fmc", "SDCKE1"), (quote!(crate::fmc::SDCKE1Pin), quote!())),
|
||||
(("fmc", "SDCLK"), (quote!(crate::fmc::SDCLKPin), quote!())),
|
||||
(("fmc", "NBL0"), (quote!(crate::fmc::NBL0Pin), quote!())),
|
||||
(("fmc", "NBL1"), (quote!(crate::fmc::NBL1Pin), quote!())),
|
||||
(("fmc", "NBL2"), (quote!(crate::fmc::NBL2Pin), quote!())),
|
||||
(("fmc", "NBL3"), (quote!(crate::fmc::NBL3Pin), quote!())),
|
||||
(("fmc", "INT"), (quote!(crate::fmc::INTPin), quote!())),
|
||||
(("fmc", "NL"), (quote!(crate::fmc::NLPin), quote!())),
|
||||
(("fmc", "NWAIT"), (quote!(crate::fmc::NWaitPin), quote!())),
|
||||
(("fmc", "NE1"), (quote!(crate::fmc::NE1Pin), quote!())),
|
||||
(("fmc", "NE2"), (quote!(crate::fmc::NE2Pin), quote!())),
|
||||
(("fmc", "NE3"), (quote!(crate::fmc::NE3Pin), quote!())),
|
||||
(("fmc", "NE4"), (quote!(crate::fmc::NE4Pin), quote!())),
|
||||
(("fmc", "NCE"), (quote!(crate::fmc::NCEPin), quote!())),
|
||||
(("fmc", "NOE"), (quote!(crate::fmc::NOEPin), quote!())),
|
||||
(("fmc", "NWE"), (quote!(crate::fmc::NWEPin), quote!())),
|
||||
(("fmc", "Clk"), (quote!(crate::fmc::ClkPin), quote!())),
|
||||
(("fmc", "BA0"), (quote!(crate::fmc::BA0Pin), quote!())),
|
||||
(("fmc", "BA1"), (quote!(crate::fmc::BA1Pin), quote!())),
|
||||
(("timer", "CH1"), (quote!(crate::pwm::Channel1Pin), quote!())),
|
||||
(("timer", "CH1N"), (quote!(crate::pwm::Channel1ComplementaryPin), quote!())),
|
||||
(("timer", "CH2"), (quote!(crate::pwm::Channel2Pin), quote!())),
|
||||
(("timer", "CH2N"), (quote!(crate::pwm::Channel2ComplementaryPin), quote!())),
|
||||
(("timer", "CH3"), (quote!(crate::pwm::Channel3Pin), quote!())),
|
||||
(("timer", "CH3N"), (quote!(crate::pwm::Channel3ComplementaryPin), quote!())),
|
||||
(("timer", "CH4"), (quote!(crate::pwm::Channel4Pin), quote!())),
|
||||
(("timer", "CH4N"), (quote!(crate::pwm::Channel4ComplementaryPin), quote!())),
|
||||
(("timer", "ETR"), (quote!(crate::pwm::ExternalTriggerPin), quote!())),
|
||||
(("timer", "BKIN"), (quote!(crate::pwm::BreakInputPin), quote!())),
|
||||
(("timer", "BKIN_COMP1"), (quote!(crate::pwm::BreakInputComparator1Pin), quote!())),
|
||||
(("timer", "BKIN_COMP2"), (quote!(crate::pwm::BreakInputComparator2Pin), quote!())),
|
||||
(("timer", "BKIN2"), (quote!(crate::pwm::BreakInput2Pin), quote!())),
|
||||
(("timer", "BKIN2_COMP1"), (quote!(crate::pwm::BreakInput2Comparator1Pin), quote!())),
|
||||
(("timer", "BKIN2_COMP2"), (quote!(crate::pwm::BreakInput2Comparator2Pin), quote!())),
|
||||
(("sdmmc", "CK"), (quote!(crate::sdmmc::CkPin), quote!())),
|
||||
(("sdmmc", "CMD"), (quote!(crate::sdmmc::CmdPin), quote!())),
|
||||
(("sdmmc", "D0"), (quote!(crate::sdmmc::D0Pin), quote!())),
|
||||
(("sdmmc", "D1"), (quote!(crate::sdmmc::D1Pin), quote!())),
|
||||
(("sdmmc", "D2"), (quote!(crate::sdmmc::D2Pin), quote!())),
|
||||
(("sdmmc", "D3"), (quote!(crate::sdmmc::D3Pin), quote!())),
|
||||
(("sdmmc", "D4"), (quote!(crate::sdmmc::D4Pin), quote!())),
|
||||
(("sdmmc", "D5"), (quote!(crate::sdmmc::D5Pin), quote!())),
|
||||
(("sdmmc", "D6"), (quote!(crate::sdmmc::D6Pin), quote!())),
|
||||
(("sdmmc", "D6"), (quote!(crate::sdmmc::D7Pin), quote!())),
|
||||
(("sdmmc", "D8"), (quote!(crate::sdmmc::D8Pin), quote!())),
|
||||
// (kind, signal) => trait
|
||||
(("usart", "TX"), quote!(crate::usart::TxPin)),
|
||||
(("usart", "RX"), quote!(crate::usart::RxPin)),
|
||||
(("usart", "CTS"), quote!(crate::usart::CtsPin)),
|
||||
(("usart", "RTS"), quote!(crate::usart::RtsPin)),
|
||||
(("usart", "CK"), quote!(crate::usart::CkPin)),
|
||||
(("usart", "TX"), quote!(crate::usart::TxPin)),
|
||||
(("usart", "RX"), quote!(crate::usart::RxPin)),
|
||||
(("usart", "CTS"), quote!(crate::usart::CtsPin)),
|
||||
(("usart", "RTS"), quote!(crate::usart::RtsPin)),
|
||||
(("usart", "CK"), quote!(crate::usart::CkPin)),
|
||||
(("spi", "SCK"), quote!(crate::spi::SckPin)),
|
||||
(("spi", "MOSI"), quote!(crate::spi::MosiPin)),
|
||||
(("spi", "MISO"), quote!(crate::spi::MisoPin)),
|
||||
(("i2c", "SDA"), quote!(crate::i2c::SdaPin)),
|
||||
(("i2c", "SCL"), quote!(crate::i2c::SclPin)),
|
||||
(("rcc", "MCO_1"), quote!(crate::rcc::McoPin)),
|
||||
(("rcc", "MCO_2"), quote!(crate::rcc::McoPin)),
|
||||
(("dcmi", "D0"), quote!(crate::dcmi::D0Pin)),
|
||||
(("dcmi", "D1"), quote!(crate::dcmi::D1Pin)),
|
||||
(("dcmi", "D2"), quote!(crate::dcmi::D2Pin)),
|
||||
(("dcmi", "D3"), quote!(crate::dcmi::D3Pin)),
|
||||
(("dcmi", "D4"), quote!(crate::dcmi::D4Pin)),
|
||||
(("dcmi", "D5"), quote!(crate::dcmi::D5Pin)),
|
||||
(("dcmi", "D6"), quote!(crate::dcmi::D6Pin)),
|
||||
(("dcmi", "D7"), quote!(crate::dcmi::D7Pin)),
|
||||
(("dcmi", "D8"), quote!(crate::dcmi::D8Pin)),
|
||||
(("dcmi", "D9"), quote!(crate::dcmi::D9Pin)),
|
||||
(("dcmi", "D10"), quote!(crate::dcmi::D10Pin)),
|
||||
(("dcmi", "D11"), quote!(crate::dcmi::D11Pin)),
|
||||
(("dcmi", "D12"), quote!(crate::dcmi::D12Pin)),
|
||||
(("dcmi", "D13"), quote!(crate::dcmi::D13Pin)),
|
||||
(("dcmi", "HSYNC"), quote!(crate::dcmi::HSyncPin)),
|
||||
(("dcmi", "VSYNC"), quote!(crate::dcmi::VSyncPin)),
|
||||
(("dcmi", "PIXCLK"), quote!(crate::dcmi::PixClkPin)),
|
||||
(("otgfs", "DP"), quote!(crate::usb_otg::DpPin)),
|
||||
(("otgfs", "DM"), quote!(crate::usb_otg::DmPin)),
|
||||
(("otghs", "DP"), quote!(crate::usb_otg::DpPin)),
|
||||
(("otghs", "DM"), quote!(crate::usb_otg::DmPin)),
|
||||
(("otghs", "ULPI_CK"), quote!(crate::usb_otg::UlpiClkPin)),
|
||||
(("otghs", "ULPI_DIR"), quote!(crate::usb_otg::UlpiDirPin)),
|
||||
(("otghs", "ULPI_NXT"), quote!(crate::usb_otg::UlpiNxtPin)),
|
||||
(("otghs", "ULPI_STP"), quote!(crate::usb_otg::UlpiStpPin)),
|
||||
(("otghs", "ULPI_D0"), quote!(crate::usb_otg::UlpiD0Pin)),
|
||||
(("otghs", "ULPI_D1"), quote!(crate::usb_otg::UlpiD1Pin)),
|
||||
(("otghs", "ULPI_D2"), quote!(crate::usb_otg::UlpiD2Pin)),
|
||||
(("otghs", "ULPI_D3"), quote!(crate::usb_otg::UlpiD3Pin)),
|
||||
(("otghs", "ULPI_D4"), quote!(crate::usb_otg::UlpiD4Pin)),
|
||||
(("otghs", "ULPI_D5"), quote!(crate::usb_otg::UlpiD5Pin)),
|
||||
(("otghs", "ULPI_D6"), quote!(crate::usb_otg::UlpiD6Pin)),
|
||||
(("otghs", "ULPI_D7"), quote!(crate::usb_otg::UlpiD7Pin)),
|
||||
(("can", "TX"), quote!(crate::can::TxPin)),
|
||||
(("can", "RX"), quote!(crate::can::RxPin)),
|
||||
(("eth", "REF_CLK"), quote!(crate::eth::RefClkPin)),
|
||||
(("eth", "MDIO"), quote!(crate::eth::MDIOPin)),
|
||||
(("eth", "MDC"), quote!(crate::eth::MDCPin)),
|
||||
(("eth", "CRS_DV"), quote!(crate::eth::CRSPin)),
|
||||
(("eth", "RXD0"), quote!(crate::eth::RXD0Pin)),
|
||||
(("eth", "RXD1"), quote!(crate::eth::RXD1Pin)),
|
||||
(("eth", "TXD0"), quote!(crate::eth::TXD0Pin)),
|
||||
(("eth", "TXD1"), quote!(crate::eth::TXD1Pin)),
|
||||
(("eth", "TX_EN"), quote!(crate::eth::TXEnPin)),
|
||||
(("fmc", "A0"), quote!(crate::fmc::A0Pin)),
|
||||
(("fmc", "A1"), quote!(crate::fmc::A1Pin)),
|
||||
(("fmc", "A2"), quote!(crate::fmc::A2Pin)),
|
||||
(("fmc", "A3"), quote!(crate::fmc::A3Pin)),
|
||||
(("fmc", "A4"), quote!(crate::fmc::A4Pin)),
|
||||
(("fmc", "A5"), quote!(crate::fmc::A5Pin)),
|
||||
(("fmc", "A6"), quote!(crate::fmc::A6Pin)),
|
||||
(("fmc", "A7"), quote!(crate::fmc::A7Pin)),
|
||||
(("fmc", "A8"), quote!(crate::fmc::A8Pin)),
|
||||
(("fmc", "A9"), quote!(crate::fmc::A9Pin)),
|
||||
(("fmc", "A10"), quote!(crate::fmc::A10Pin)),
|
||||
(("fmc", "A11"), quote!(crate::fmc::A11Pin)),
|
||||
(("fmc", "A12"), quote!(crate::fmc::A12Pin)),
|
||||
(("fmc", "A13"), quote!(crate::fmc::A13Pin)),
|
||||
(("fmc", "A14"), quote!(crate::fmc::A14Pin)),
|
||||
(("fmc", "A15"), quote!(crate::fmc::A15Pin)),
|
||||
(("fmc", "A16"), quote!(crate::fmc::A16Pin)),
|
||||
(("fmc", "A17"), quote!(crate::fmc::A17Pin)),
|
||||
(("fmc", "A18"), quote!(crate::fmc::A18Pin)),
|
||||
(("fmc", "A19"), quote!(crate::fmc::A19Pin)),
|
||||
(("fmc", "A20"), quote!(crate::fmc::A20Pin)),
|
||||
(("fmc", "A21"), quote!(crate::fmc::A21Pin)),
|
||||
(("fmc", "A22"), quote!(crate::fmc::A22Pin)),
|
||||
(("fmc", "A23"), quote!(crate::fmc::A23Pin)),
|
||||
(("fmc", "A24"), quote!(crate::fmc::A24Pin)),
|
||||
(("fmc", "A25"), quote!(crate::fmc::A25Pin)),
|
||||
(("fmc", "D0"), quote!(crate::fmc::D0Pin)),
|
||||
(("fmc", "D1"), quote!(crate::fmc::D1Pin)),
|
||||
(("fmc", "D2"), quote!(crate::fmc::D2Pin)),
|
||||
(("fmc", "D3"), quote!(crate::fmc::D3Pin)),
|
||||
(("fmc", "D4"), quote!(crate::fmc::D4Pin)),
|
||||
(("fmc", "D5"), quote!(crate::fmc::D5Pin)),
|
||||
(("fmc", "D6"), quote!(crate::fmc::D6Pin)),
|
||||
(("fmc", "D7"), quote!(crate::fmc::D7Pin)),
|
||||
(("fmc", "D8"), quote!(crate::fmc::D8Pin)),
|
||||
(("fmc", "D9"), quote!(crate::fmc::D9Pin)),
|
||||
(("fmc", "D10"), quote!(crate::fmc::D10Pin)),
|
||||
(("fmc", "D11"), quote!(crate::fmc::D11Pin)),
|
||||
(("fmc", "D12"), quote!(crate::fmc::D12Pin)),
|
||||
(("fmc", "D13"), quote!(crate::fmc::D13Pin)),
|
||||
(("fmc", "D14"), quote!(crate::fmc::D14Pin)),
|
||||
(("fmc", "D15"), quote!(crate::fmc::D15Pin)),
|
||||
(("fmc", "D16"), quote!(crate::fmc::D16Pin)),
|
||||
(("fmc", "D17"), quote!(crate::fmc::D17Pin)),
|
||||
(("fmc", "D18"), quote!(crate::fmc::D18Pin)),
|
||||
(("fmc", "D19"), quote!(crate::fmc::D19Pin)),
|
||||
(("fmc", "D20"), quote!(crate::fmc::D20Pin)),
|
||||
(("fmc", "D21"), quote!(crate::fmc::D21Pin)),
|
||||
(("fmc", "D22"), quote!(crate::fmc::D22Pin)),
|
||||
(("fmc", "D23"), quote!(crate::fmc::D23Pin)),
|
||||
(("fmc", "D24"), quote!(crate::fmc::D24Pin)),
|
||||
(("fmc", "D25"), quote!(crate::fmc::D25Pin)),
|
||||
(("fmc", "D26"), quote!(crate::fmc::D26Pin)),
|
||||
(("fmc", "D27"), quote!(crate::fmc::D27Pin)),
|
||||
(("fmc", "D28"), quote!(crate::fmc::D28Pin)),
|
||||
(("fmc", "D29"), quote!(crate::fmc::D29Pin)),
|
||||
(("fmc", "D30"), quote!(crate::fmc::D30Pin)),
|
||||
(("fmc", "D31"), quote!(crate::fmc::D31Pin)),
|
||||
(("fmc", "DA0"), quote!(crate::fmc::DA0Pin)),
|
||||
(("fmc", "DA1"), quote!(crate::fmc::DA1Pin)),
|
||||
(("fmc", "DA2"), quote!(crate::fmc::DA2Pin)),
|
||||
(("fmc", "DA3"), quote!(crate::fmc::DA3Pin)),
|
||||
(("fmc", "DA4"), quote!(crate::fmc::DA4Pin)),
|
||||
(("fmc", "DA5"), quote!(crate::fmc::DA5Pin)),
|
||||
(("fmc", "DA6"), quote!(crate::fmc::DA6Pin)),
|
||||
(("fmc", "DA7"), quote!(crate::fmc::DA7Pin)),
|
||||
(("fmc", "DA8"), quote!(crate::fmc::DA8Pin)),
|
||||
(("fmc", "DA9"), quote!(crate::fmc::DA9Pin)),
|
||||
(("fmc", "DA10"), quote!(crate::fmc::DA10Pin)),
|
||||
(("fmc", "DA11"), quote!(crate::fmc::DA11Pin)),
|
||||
(("fmc", "DA12"), quote!(crate::fmc::DA12Pin)),
|
||||
(("fmc", "DA13"), quote!(crate::fmc::DA13Pin)),
|
||||
(("fmc", "DA14"), quote!(crate::fmc::DA14Pin)),
|
||||
(("fmc", "DA15"), quote!(crate::fmc::DA15Pin)),
|
||||
(("fmc", "SDNWE"), quote!(crate::fmc::SDNWEPin)),
|
||||
(("fmc", "SDNCAS"), quote!(crate::fmc::SDNCASPin)),
|
||||
(("fmc", "SDNRAS"), quote!(crate::fmc::SDNRASPin)),
|
||||
(("fmc", "SDNE0"), quote!(crate::fmc::SDNE0Pin)),
|
||||
(("fmc", "SDNE1"), quote!(crate::fmc::SDNE1Pin)),
|
||||
(("fmc", "SDCKE0"), quote!(crate::fmc::SDCKE0Pin)),
|
||||
(("fmc", "SDCKE1"), quote!(crate::fmc::SDCKE1Pin)),
|
||||
(("fmc", "SDCLK"), quote!(crate::fmc::SDCLKPin)),
|
||||
(("fmc", "NBL0"), quote!(crate::fmc::NBL0Pin)),
|
||||
(("fmc", "NBL1"), quote!(crate::fmc::NBL1Pin)),
|
||||
(("fmc", "NBL2"), quote!(crate::fmc::NBL2Pin)),
|
||||
(("fmc", "NBL3"), quote!(crate::fmc::NBL3Pin)),
|
||||
(("fmc", "INT"), quote!(crate::fmc::INTPin)),
|
||||
(("fmc", "NL"), quote!(crate::fmc::NLPin)),
|
||||
(("fmc", "NWAIT"), quote!(crate::fmc::NWaitPin)),
|
||||
(("fmc", "NE1"), quote!(crate::fmc::NE1Pin)),
|
||||
(("fmc", "NE2"), quote!(crate::fmc::NE2Pin)),
|
||||
(("fmc", "NE3"), quote!(crate::fmc::NE3Pin)),
|
||||
(("fmc", "NE4"), quote!(crate::fmc::NE4Pin)),
|
||||
(("fmc", "NCE"), quote!(crate::fmc::NCEPin)),
|
||||
(("fmc", "NOE"), quote!(crate::fmc::NOEPin)),
|
||||
(("fmc", "NWE"), quote!(crate::fmc::NWEPin)),
|
||||
(("fmc", "Clk"), quote!(crate::fmc::ClkPin)),
|
||||
(("fmc", "BA0"), quote!(crate::fmc::BA0Pin)),
|
||||
(("fmc", "BA1"), quote!(crate::fmc::BA1Pin)),
|
||||
(("timer", "CH1"), quote!(crate::pwm::Channel1Pin)),
|
||||
(("timer", "CH1N"), quote!(crate::pwm::Channel1ComplementaryPin)),
|
||||
(("timer", "CH2"), quote!(crate::pwm::Channel2Pin)),
|
||||
(("timer", "CH2N"), quote!(crate::pwm::Channel2ComplementaryPin)),
|
||||
(("timer", "CH3"), quote!(crate::pwm::Channel3Pin)),
|
||||
(("timer", "CH3N"), quote!(crate::pwm::Channel3ComplementaryPin)),
|
||||
(("timer", "CH4"), quote!(crate::pwm::Channel4Pin)),
|
||||
(("timer", "CH4N"), quote!(crate::pwm::Channel4ComplementaryPin)),
|
||||
(("timer", "ETR"), quote!(crate::pwm::ExternalTriggerPin)),
|
||||
(("timer", "BKIN"), quote!(crate::pwm::BreakInputPin)),
|
||||
(("timer", "BKIN_COMP1"), quote!(crate::pwm::BreakInputComparator1Pin)),
|
||||
(("timer", "BKIN_COMP2"), quote!(crate::pwm::BreakInputComparator2Pin)),
|
||||
(("timer", "BKIN2"), quote!(crate::pwm::BreakInput2Pin)),
|
||||
(("timer", "BKIN2_COMP1"), quote!(crate::pwm::BreakInput2Comparator1Pin)),
|
||||
(("timer", "BKIN2_COMP2"), quote!(crate::pwm::BreakInput2Comparator2Pin)),
|
||||
(("sdmmc", "CK"), quote!(crate::sdmmc::CkPin)),
|
||||
(("sdmmc", "CMD"), quote!(crate::sdmmc::CmdPin)),
|
||||
(("sdmmc", "D0"), quote!(crate::sdmmc::D0Pin)),
|
||||
(("sdmmc", "D1"), quote!(crate::sdmmc::D1Pin)),
|
||||
(("sdmmc", "D2"), quote!(crate::sdmmc::D2Pin)),
|
||||
(("sdmmc", "D3"), quote!(crate::sdmmc::D3Pin)),
|
||||
(("sdmmc", "D4"), quote!(crate::sdmmc::D4Pin)),
|
||||
(("sdmmc", "D5"), quote!(crate::sdmmc::D5Pin)),
|
||||
(("sdmmc", "D6"), quote!(crate::sdmmc::D6Pin)),
|
||||
(("sdmmc", "D6"), quote!(crate::sdmmc::D7Pin)),
|
||||
(("sdmmc", "D8"), quote!(crate::sdmmc::D8Pin)),
|
||||
].into();
|
||||
|
||||
for p in METADATA.peripherals {
|
||||
if let Some(regs) = &p.registers {
|
||||
for pin in p.pins {
|
||||
let key = (regs.kind, pin.signal);
|
||||
if let Some((tr, cfgs)) = signals.get(&key) {
|
||||
if let Some(tr) = signals.get(&key) {
|
||||
let mut peri = format_ident!("{}", p.name);
|
||||
let pin_name = format_ident!("{}", pin.pin);
|
||||
let af = pin.af.unwrap_or(0);
|
||||
@ -453,7 +453,6 @@ fn main() {
|
||||
}
|
||||
|
||||
g.extend(quote! {
|
||||
#cfgs
|
||||
pin_trait_impl!(#tr, #peri, #pin_name, #af);
|
||||
})
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
#![macro_use]
|
||||
|
||||
#[cfg(feature = "net")]
|
||||
#[cfg_attr(any(eth_v1a, eth_v1b, eth_v1c), path = "v1/mod.rs")]
|
||||
#[cfg_attr(eth_v2, path = "v2/mod.rs")]
|
||||
mod _version;
|
||||
pub mod generic_smi;
|
||||
|
||||
#[cfg(feature = "net")]
|
||||
pub use _version::*;
|
||||
|
||||
/// Station Management Interface (SMI) on an ethernet PHY
|
||||
|
@ -39,7 +39,7 @@ pub mod can;
|
||||
pub mod dac;
|
||||
#[cfg(dcmi)]
|
||||
pub mod dcmi;
|
||||
#[cfg(all(eth, feature = "net"))]
|
||||
#[cfg(eth)]
|
||||
pub mod eth;
|
||||
#[cfg(feature = "exti")]
|
||||
pub mod exti;
|
||||
|
238
embassy-stm32/src/usart/buffered.rs
Normal file
238
embassy-stm32/src/usart/buffered.rs
Normal file
@ -0,0 +1,238 @@
|
||||
use atomic_polyfill::{compiler_fence, Ordering};
|
||||
use core::future::Future;
|
||||
use core::task::Poll;
|
||||
use embassy::waitqueue::WakerRegistration;
|
||||
use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
|
||||
use embassy_hal_common::ring_buffer::RingBuffer;
|
||||
use futures::future::poll_fn;
|
||||
|
||||
use super::*;
|
||||
|
||||
pub struct State<'d, T: Instance>(StateStorage<StateInner<'d, T>>);
|
||||
impl<'d, T: Instance> State<'d, T> {
|
||||
pub fn new() -> Self {
|
||||
Self(StateStorage::new())
|
||||
}
|
||||
}
|
||||
|
||||
struct StateInner<'d, T: Instance> {
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
|
||||
rx_waker: WakerRegistration,
|
||||
rx: RingBuffer<'d>,
|
||||
|
||||
tx_waker: WakerRegistration,
|
||||
tx: RingBuffer<'d>,
|
||||
}
|
||||
|
||||
unsafe impl<'d, T: Instance> Send for StateInner<'d, T> {}
|
||||
unsafe impl<'d, T: Instance> Sync for StateInner<'d, T> {}
|
||||
|
||||
pub struct BufferedUart<'d, T: Instance> {
|
||||
inner: PeripheralMutex<'d, StateInner<'d, T>>,
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> Unpin for BufferedUart<'d, T> {}
|
||||
|
||||
impl<'d, T: Instance> BufferedUart<'d, T> {
|
||||
pub unsafe fn new(
|
||||
state: &'d mut State<'d, T>,
|
||||
_uart: Uart<'d, T, NoDma, NoDma>,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
tx_buffer: &'d mut [u8],
|
||||
rx_buffer: &'d mut [u8],
|
||||
) -> BufferedUart<'d, T> {
|
||||
unborrow!(irq);
|
||||
|
||||
let r = T::regs();
|
||||
r.cr1().modify(|w| {
|
||||
w.set_rxneie(true);
|
||||
w.set_idleie(true);
|
||||
});
|
||||
|
||||
Self {
|
||||
inner: PeripheralMutex::new_unchecked(irq, &mut state.0, move || StateInner {
|
||||
phantom: PhantomData,
|
||||
tx: RingBuffer::new(tx_buffer),
|
||||
tx_waker: WakerRegistration::new(),
|
||||
|
||||
rx: RingBuffer::new(rx_buffer),
|
||||
rx_waker: WakerRegistration::new(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> StateInner<'d, T>
|
||||
where
|
||||
Self: 'd,
|
||||
{
|
||||
fn on_rx(&mut self) {
|
||||
let r = T::regs();
|
||||
unsafe {
|
||||
let sr = sr(r).read();
|
||||
clear_interrupt_flags(r, sr);
|
||||
|
||||
// This read also clears the error and idle interrupt flags on v1.
|
||||
let b = rdr(r).read_volatile();
|
||||
|
||||
if sr.rxne() {
|
||||
if sr.pe() {
|
||||
warn!("Parity error");
|
||||
}
|
||||
if sr.fe() {
|
||||
warn!("Framing error");
|
||||
}
|
||||
if sr.ne() {
|
||||
warn!("Noise error");
|
||||
}
|
||||
if sr.ore() {
|
||||
warn!("Overrun error");
|
||||
}
|
||||
|
||||
let buf = self.rx.push_buf();
|
||||
if !buf.is_empty() {
|
||||
buf[0] = b;
|
||||
self.rx.push(1);
|
||||
} else {
|
||||
warn!("RX buffer full, discard received byte");
|
||||
}
|
||||
|
||||
if self.rx.is_full() {
|
||||
self.rx_waker.wake();
|
||||
}
|
||||
}
|
||||
|
||||
if sr.idle() {
|
||||
self.rx_waker.wake();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn on_tx(&mut self) {
|
||||
let r = T::regs();
|
||||
unsafe {
|
||||
if sr(r).read().txe() {
|
||||
let buf = self.tx.pop_buf();
|
||||
if !buf.is_empty() {
|
||||
r.cr1().modify(|w| {
|
||||
w.set_txeie(true);
|
||||
});
|
||||
tdr(r).write_volatile(buf[0].into());
|
||||
self.tx.pop(1);
|
||||
self.tx_waker.wake();
|
||||
} else {
|
||||
// Disable interrupt until we have something to transmit again
|
||||
r.cr1().modify(|w| {
|
||||
w.set_txeie(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> PeripheralState for StateInner<'d, T>
|
||||
where
|
||||
Self: 'd,
|
||||
{
|
||||
type Interrupt = T::Interrupt;
|
||||
fn on_interrupt(&mut self) {
|
||||
self.on_rx();
|
||||
self.on_tx();
|
||||
}
|
||||
}
|
||||
|
||||
impl embedded_io::Error for Error {
|
||||
fn kind(&self) -> embedded_io::ErrorKind {
|
||||
embedded_io::ErrorKind::Other
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> embedded_io::Io for BufferedUart<'d, T> {
|
||||
type Error = Error;
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> embedded_io::asynch::Read for BufferedUart<'d, T> {
|
||||
type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
||||
poll_fn(move |cx| {
|
||||
let mut do_pend = false;
|
||||
let res = self.inner.with(|state| {
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
|
||||
// We have data ready in buffer? Return it.
|
||||
let data = state.rx.pop_buf();
|
||||
if !data.is_empty() {
|
||||
let len = data.len().min(buf.len());
|
||||
buf[..len].copy_from_slice(&data[..len]);
|
||||
|
||||
if state.rx.is_full() {
|
||||
do_pend = true;
|
||||
}
|
||||
state.rx.pop(len);
|
||||
|
||||
return Poll::Ready(Ok(len));
|
||||
}
|
||||
|
||||
state.rx_waker.register(cx.waker());
|
||||
Poll::Pending
|
||||
});
|
||||
|
||||
if do_pend {
|
||||
self.inner.pend();
|
||||
}
|
||||
|
||||
res
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> embedded_io::asynch::Write for BufferedUart<'d, T> {
|
||||
type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
|
||||
poll_fn(move |cx| {
|
||||
let (poll, empty) = self.inner.with(|state| {
|
||||
let empty = state.tx.is_empty();
|
||||
let tx_buf = state.tx.push_buf();
|
||||
if tx_buf.is_empty() {
|
||||
state.tx_waker.register(cx.waker());
|
||||
return (Poll::Pending, empty);
|
||||
}
|
||||
|
||||
let n = core::cmp::min(tx_buf.len(), buf.len());
|
||||
tx_buf[..n].copy_from_slice(&buf[..n]);
|
||||
state.tx.push(n);
|
||||
|
||||
(Poll::Ready(Ok(n)), empty)
|
||||
});
|
||||
if empty {
|
||||
self.inner.pend();
|
||||
}
|
||||
poll
|
||||
})
|
||||
}
|
||||
|
||||
type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
|
||||
poll_fn(move |cx| {
|
||||
self.inner.with(|state| {
|
||||
if !state.tx.is_empty() {
|
||||
state.tx_waker.register(cx.waker());
|
||||
return Poll::Pending;
|
||||
}
|
||||
|
||||
Poll::Ready(Ok(()))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
@ -424,227 +424,10 @@ cfg_if::cfg_if! {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
pub use buffered::*;
|
||||
mod buffered {
|
||||
use atomic_polyfill::{compiler_fence, Ordering};
|
||||
use core::pin::Pin;
|
||||
use core::task::Context;
|
||||
use core::task::Poll;
|
||||
use embassy::waitqueue::WakerRegistration;
|
||||
use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
|
||||
use embassy_hal_common::ring_buffer::RingBuffer;
|
||||
|
||||
use super::*;
|
||||
|
||||
pub struct State<'d, T: Instance>(StateStorage<StateInner<'d, T>>);
|
||||
impl<'d, T: Instance> State<'d, T> {
|
||||
pub fn new() -> Self {
|
||||
Self(StateStorage::new())
|
||||
}
|
||||
}
|
||||
|
||||
struct StateInner<'d, T: Instance> {
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
|
||||
rx_waker: WakerRegistration,
|
||||
rx: RingBuffer<'d>,
|
||||
|
||||
tx_waker: WakerRegistration,
|
||||
tx: RingBuffer<'d>,
|
||||
}
|
||||
|
||||
unsafe impl<'d, T: Instance> Send for StateInner<'d, T> {}
|
||||
unsafe impl<'d, T: Instance> Sync for StateInner<'d, T> {}
|
||||
|
||||
pub struct BufferedUart<'d, T: Instance> {
|
||||
inner: PeripheralMutex<'d, StateInner<'d, T>>,
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> Unpin for BufferedUart<'d, T> {}
|
||||
|
||||
impl<'d, T: Instance> BufferedUart<'d, T> {
|
||||
pub unsafe fn new(
|
||||
state: &'d mut State<'d, T>,
|
||||
_uart: Uart<'d, T, NoDma, NoDma>,
|
||||
irq: impl Unborrow<Target = T::Interrupt> + 'd,
|
||||
tx_buffer: &'d mut [u8],
|
||||
rx_buffer: &'d mut [u8],
|
||||
) -> BufferedUart<'d, T> {
|
||||
unborrow!(irq);
|
||||
|
||||
let r = T::regs();
|
||||
r.cr1().modify(|w| {
|
||||
w.set_rxneie(true);
|
||||
w.set_idleie(true);
|
||||
});
|
||||
|
||||
Self {
|
||||
inner: PeripheralMutex::new_unchecked(irq, &mut state.0, move || StateInner {
|
||||
phantom: PhantomData,
|
||||
tx: RingBuffer::new(tx_buffer),
|
||||
tx_waker: WakerRegistration::new(),
|
||||
|
||||
rx: RingBuffer::new(rx_buffer),
|
||||
rx_waker: WakerRegistration::new(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> StateInner<'d, T>
|
||||
where
|
||||
Self: 'd,
|
||||
{
|
||||
fn on_rx(&mut self) {
|
||||
let r = T::regs();
|
||||
unsafe {
|
||||
let sr = sr(r).read();
|
||||
clear_interrupt_flags(r, sr);
|
||||
|
||||
// This read also clears the error and idle interrupt flags on v1.
|
||||
let b = rdr(r).read_volatile();
|
||||
|
||||
if sr.rxne() {
|
||||
if sr.pe() {
|
||||
warn!("Parity error");
|
||||
}
|
||||
if sr.fe() {
|
||||
warn!("Framing error");
|
||||
}
|
||||
if sr.ne() {
|
||||
warn!("Noise error");
|
||||
}
|
||||
if sr.ore() {
|
||||
warn!("Overrun error");
|
||||
}
|
||||
|
||||
let buf = self.rx.push_buf();
|
||||
if !buf.is_empty() {
|
||||
buf[0] = b;
|
||||
self.rx.push(1);
|
||||
} else {
|
||||
warn!("RX buffer full, discard received byte");
|
||||
}
|
||||
|
||||
if self.rx.is_full() {
|
||||
self.rx_waker.wake();
|
||||
}
|
||||
}
|
||||
|
||||
if sr.idle() {
|
||||
self.rx_waker.wake();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn on_tx(&mut self) {
|
||||
let r = T::regs();
|
||||
unsafe {
|
||||
if sr(r).read().txe() {
|
||||
let buf = self.tx.pop_buf();
|
||||
if !buf.is_empty() {
|
||||
r.cr1().modify(|w| {
|
||||
w.set_txeie(true);
|
||||
});
|
||||
tdr(r).write_volatile(buf[0].into());
|
||||
self.tx.pop(1);
|
||||
self.tx_waker.wake();
|
||||
} else {
|
||||
// Disable interrupt until we have something to transmit again
|
||||
r.cr1().modify(|w| {
|
||||
w.set_txeie(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> PeripheralState for StateInner<'d, T>
|
||||
where
|
||||
Self: 'd,
|
||||
{
|
||||
type Interrupt = T::Interrupt;
|
||||
fn on_interrupt(&mut self) {
|
||||
self.on_rx();
|
||||
self.on_tx();
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> embassy::io::AsyncBufRead for BufferedUart<'d, T> {
|
||||
fn poll_fill_buf(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Result<&[u8], embassy::io::Error>> {
|
||||
self.inner.with(|state| {
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
|
||||
// We have data ready in buffer? Return it.
|
||||
let buf = state.rx.pop_buf();
|
||||
if !buf.is_empty() {
|
||||
let buf: &[u8] = buf;
|
||||
// Safety: buffer lives as long as uart
|
||||
let buf: &[u8] = unsafe { core::mem::transmute(buf) };
|
||||
return Poll::Ready(Ok(buf));
|
||||
}
|
||||
|
||||
state.rx_waker.register(cx.waker());
|
||||
Poll::<Result<&[u8], embassy::io::Error>>::Pending
|
||||
})
|
||||
}
|
||||
fn consume(mut self: Pin<&mut Self>, amt: usize) {
|
||||
let signal = self.inner.with(|state| {
|
||||
let full = state.rx.is_full();
|
||||
state.rx.pop(amt);
|
||||
full
|
||||
});
|
||||
if signal {
|
||||
self.inner.pend();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> embassy::io::AsyncWrite for BufferedUart<'d, T> {
|
||||
fn poll_write(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
buf: &[u8],
|
||||
) -> Poll<Result<usize, embassy::io::Error>> {
|
||||
let (poll, empty) = self.inner.with(|state| {
|
||||
let empty = state.tx.is_empty();
|
||||
let tx_buf = state.tx.push_buf();
|
||||
if tx_buf.is_empty() {
|
||||
state.tx_waker.register(cx.waker());
|
||||
return (Poll::Pending, empty);
|
||||
}
|
||||
|
||||
let n = core::cmp::min(tx_buf.len(), buf.len());
|
||||
tx_buf[..n].copy_from_slice(&buf[..n]);
|
||||
state.tx.push(n);
|
||||
|
||||
(Poll::Ready(Ok(n)), empty)
|
||||
});
|
||||
if empty {
|
||||
self.inner.pend();
|
||||
}
|
||||
poll
|
||||
}
|
||||
|
||||
fn poll_flush(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Result<(), embassy::io::Error>> {
|
||||
self.inner.with(|state| {
|
||||
if !state.tx.is_empty() {
|
||||
state.tx_waker.register(cx.waker());
|
||||
return Poll::Pending;
|
||||
}
|
||||
|
||||
Poll::Ready(Ok(()))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "nightly")]
|
||||
mod buffered;
|
||||
|
||||
#[cfg(usart_v1)]
|
||||
fn tdr(r: crate::pac::usart::Usart) -> *mut u8 {
|
||||
@ -662,6 +445,7 @@ fn sr(r: crate::pac::usart::Usart) -> crate::pac::common::Reg<regs::Sr, crate::p
|
||||
}
|
||||
|
||||
#[cfg(usart_v1)]
|
||||
#[allow(unused)]
|
||||
unsafe fn clear_interrupt_flags(_r: crate::pac::usart::Usart, _sr: regs::Sr) {
|
||||
// On v1 the flags are cleared implicitly by reads and writes to DR.
|
||||
}
|
||||
@ -682,6 +466,7 @@ fn sr(r: crate::pac::usart::Usart) -> crate::pac::common::Reg<regs::Ixr, crate::
|
||||
}
|
||||
|
||||
#[cfg(usart_v2)]
|
||||
#[allow(unused)]
|
||||
unsafe fn clear_interrupt_flags(r: crate::pac::usart::Usart, sr: regs::Ixr) {
|
||||
r.icr().write(|w| *w = sr);
|
||||
}
|
||||
|
Reference in New Issue
Block a user