1#![no_std]
5#![deny(missing_docs)]
6
7#[cfg(not(feature = "device-selected"))]
8compile_error!("No device was selected! Exactly one stm32fxxx feature must be selected.");
9
10#[cfg(feature = "stm32f7xx-hal")]
12pub use stm32f7xx_hal as hal;
13
14#[cfg(feature = "stm32f4xx-hal")]
16pub use stm32f4xx_hal as hal;
17
18#[cfg(feature = "stm32f1xx-hal")]
20pub use stm32f1xx_hal as hal;
21
22#[cfg(feature = "device-selected")]
23pub use hal::pac as stm32;
24#[cfg(feature = "device-selected")]
25use hal::rcc::Clocks;
26
27#[cfg(feature = "device-selected")]
28pub mod dma;
29
30#[cfg(feature = "device-selected")]
31pub mod mac;
32
33#[cfg(feature = "device-selected")]
34pub mod setup;
35#[doc(inline)]
36#[cfg(feature = "device-selected")]
37pub use setup::{EthPins, Parts, PartsIn};
38
39#[cfg(feature = "device-selected")]
40pub(crate) mod peripherals;
41
42#[cfg(feature = "ptp")]
43pub mod ptp;
44
45#[cfg(feature = "device-selected")]
46use {
47 dma::{EthernetDMA, RxRingEntry, TxRingEntry},
48 mac::{EthernetMAC, EthernetMACWithMii, MdcPin, MdioPin, Speed, WrongClock},
49 setup::*,
50};
51
52#[cfg(all(feature = "device-selected", feature = "ptp"))]
53use ptp::EthernetPTP;
54
55#[cfg_attr(feature = "defmt", derive(defmt::Format))]
58#[derive(Clone, Copy, Debug, PartialEq)]
59pub struct InterruptReason {
60 pub rx: bool,
62 pub tx: bool,
64 pub dma_error: bool,
66 #[cfg(all(feature = "ptp", not(feature = "stm32f1xx-hal")))]
67 pub time_passed: bool,
70}
71
72#[cfg(feature = "device-selected")]
77pub fn eth_interrupt_handler() -> InterruptReason {
78 let dma = EthernetDMA::interrupt_handler();
79
80 #[cfg(all(feature = "ptp", not(feature = "stm32f1xx-hal")))]
81 let is_time_trigger = EthernetPTP::interrupt_handler();
82
83 InterruptReason {
84 rx: dma.is_rx,
85 tx: dma.is_tx,
86 dma_error: dma.is_error,
87 #[cfg(all(feature = "ptp", not(feature = "stm32f1xx-hal")))]
88 time_passed: is_time_trigger,
89 }
90}
91
92#[cfg(feature = "device-selected")]
111pub fn new<'rx, 'tx, REFCLK, CRS, TXEN, TXD0, TXD1, RXD0, RXD1>(
112 parts: PartsIn,
113 rx_buffer: &'rx mut [RxRingEntry],
114 tx_buffer: &'tx mut [TxRingEntry],
115 clocks: Clocks,
116 pins: EthPins<REFCLK, CRS, TXEN, TXD0, TXD1, RXD0, RXD1>,
117) -> Result<Parts<'rx, 'tx, EthernetMAC>, WrongClock>
118where
119 REFCLK: RmiiRefClk + AlternateVeryHighSpeed,
120 CRS: RmiiCrsDv + AlternateVeryHighSpeed,
121 TXEN: RmiiTxEN + AlternateVeryHighSpeed,
122 TXD0: RmiiTxD0 + AlternateVeryHighSpeed,
123 TXD1: RmiiTxD1 + AlternateVeryHighSpeed,
124 RXD0: RmiiRxD0 + AlternateVeryHighSpeed,
125 RXD1: RmiiRxD1 + AlternateVeryHighSpeed,
126{
127 pins.setup_pins();
129
130 setup::setup();
132
133 let eth_mac = parts.mac.into();
134
135 let dma = EthernetDMA::new(parts.dma.into(), rx_buffer, tx_buffer);
137
138 #[cfg(feature = "ptp")]
140 let ptp = EthernetPTP::new(parts.ptp.into(), clocks, &dma);
141
142 let mac = EthernetMAC::new(eth_mac, parts.mmc, clocks, Speed::FullDuplexBase100Tx, &dma)?;
144
145 let parts = Parts {
146 mac,
147 dma,
148 #[cfg(feature = "ptp")]
149 ptp,
150 };
151
152 Ok(parts)
153}
154
155#[cfg(feature = "device-selected")]
176pub fn new_with_mii<'rx, 'tx, REFCLK, CRS, TXEN, TXD0, TXD1, RXD0, RXD1, MDIO, MDC>(
177 parts: PartsIn,
178 rx_buffer: &'rx mut [RxRingEntry],
179 tx_buffer: &'tx mut [TxRingEntry],
180 clocks: Clocks,
181 pins: EthPins<REFCLK, CRS, TXEN, TXD0, TXD1, RXD0, RXD1>,
182 mdio: MDIO,
183 mdc: MDC,
184) -> Result<Parts<'rx, 'tx, EthernetMACWithMii<MDIO, MDC>>, WrongClock>
185where
186 REFCLK: RmiiRefClk + AlternateVeryHighSpeed,
187 CRS: RmiiCrsDv + AlternateVeryHighSpeed,
188 TXEN: RmiiTxEN + AlternateVeryHighSpeed,
189 TXD0: RmiiTxD0 + AlternateVeryHighSpeed,
190 TXD1: RmiiTxD1 + AlternateVeryHighSpeed,
191 RXD0: RmiiRxD0 + AlternateVeryHighSpeed,
192 RXD1: RmiiRxD1 + AlternateVeryHighSpeed,
193 MDIO: MdioPin,
194 MDC: MdcPin,
195{
196 pins.setup_pins();
198
199 setup::setup();
201
202 let eth_mac = parts.mac.into();
203
204 let dma = EthernetDMA::new(parts.dma.into(), rx_buffer, tx_buffer);
206
207 #[cfg(feature = "ptp")]
209 let ptp = EthernetPTP::new(parts.ptp.into(), clocks, &dma);
210
211 let mac = EthernetMAC::new(eth_mac, parts.mmc, clocks, Speed::FullDuplexBase100Tx, &dma)?
213 .with_mii(mdio, mdc);
214
215 let parts = Parts {
216 mac,
217 dma,
218 #[cfg(feature = "ptp")]
219 ptp,
220 };
221
222 Ok(parts)
223}
224
225#[cfg(doctest)]
229mod test_readme {
230 macro_rules! external_doc_test {
231 ($x:expr) => {
232 #[doc = $x]
233 extern "C" {}
234 };
235 }
236 external_doc_test!(include_str!("../README.md"));
237}