aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/eth
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-12-26 03:33:49 +0100
committerDario Nieuwenhuis <[email protected]>2022-12-26 04:49:08 +0100
commit1f033d509afb4e590a81896de66af683fda4e706 (patch)
tree5c10000e08d00de221a770c81fb9127a35dd0343 /embassy-stm32/src/eth
parent639b3f1d5b4b2897b326edc52f66f18caaa3bd3e (diff)
net: split driver trait to a separate crate.
Diffstat (limited to 'embassy-stm32/src/eth')
-rw-r--r--embassy-stm32/src/eth/mod.rs139
-rw-r--r--embassy-stm32/src/eth/v1/mod.rs4
2 files changed, 69 insertions, 74 deletions
diff --git a/embassy-stm32/src/eth/mod.rs b/embassy-stm32/src/eth/mod.rs
index fd1b48530..9f62b61ee 100644
--- a/embassy-stm32/src/eth/mod.rs
+++ b/embassy-stm32/src/eth/mod.rs
@@ -1,14 +1,17 @@
1#![macro_use] 1#![macro_use]
2#![cfg_attr(not(feature = "embassy-net"), allow(unused))]
3 2
4#[cfg_attr(any(eth_v1a, eth_v1b, eth_v1c), path = "v1/mod.rs")] 3#[cfg_attr(any(eth_v1a, eth_v1b, eth_v1c), path = "v1/mod.rs")]
5#[cfg_attr(eth_v2, path = "v2/mod.rs")] 4#[cfg_attr(eth_v2, path = "v2/mod.rs")]
6mod _version; 5mod _version;
7pub mod generic_smi; 6pub mod generic_smi;
8 7
9pub use _version::*; 8use core::task::Context;
9
10use embassy_net_driver::{Capabilities, LinkState};
10use embassy_sync::waitqueue::AtomicWaker; 11use embassy_sync::waitqueue::AtomicWaker;
11 12
13pub use self::_version::*;
14
12#[allow(unused)] 15#[allow(unused)]
13const MTU: usize = 1514; 16const MTU: usize = 1514;
14const TX_BUFFER_SIZE: usize = 1514; 17const TX_BUFFER_SIZE: usize = 1514;
@@ -40,92 +43,84 @@ impl<const TX: usize, const RX: usize> PacketQueue<TX, RX> {
40 43
41static WAKER: AtomicWaker = AtomicWaker::new(); 44static WAKER: AtomicWaker = AtomicWaker::new();
42 45
43#[cfg(feature = "embassy-net")] 46impl<'d, T: Instance, P: PHY> embassy_net_driver::Driver for Ethernet<'d, T, P> {
44mod embassy_net_impl { 47 type RxToken<'a> = RxToken<'a, 'd> where Self: 'a;
45 use core::task::Context; 48 type TxToken<'a> = TxToken<'a, 'd> where Self: 'a;
46
47 use embassy_net::device::{Device, DeviceCapabilities, LinkState};
48
49 use super::*;
50
51 impl<'d, T: Instance, P: PHY> Device for Ethernet<'d, T, P> {
52 type RxToken<'a> = RxToken<'a, 'd> where Self: 'a;
53 type TxToken<'a> = TxToken<'a, 'd> where Self: 'a;
54 49
55 fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { 50 fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
56 WAKER.register(cx.waker()); 51 WAKER.register(cx.waker());
57 if self.rx.available().is_some() && self.tx.available().is_some() { 52 if self.rx.available().is_some() && self.tx.available().is_some() {
58 Some((RxToken { rx: &mut self.rx }, TxToken { tx: &mut self.tx })) 53 Some((RxToken { rx: &mut self.rx }, TxToken { tx: &mut self.tx }))
59 } else { 54 } else {
60 None 55 None
61 }
62 }
63
64 fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> {
65 WAKER.register(cx.waker());
66 if self.tx.available().is_some() {
67 Some(TxToken { tx: &mut self.tx })
68 } else {
69 None
70 }
71 } 56 }
57 }
72 58
73 fn capabilities(&self) -> DeviceCapabilities { 59 fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> {
74 let mut caps = DeviceCapabilities::default(); 60 WAKER.register(cx.waker());
75 caps.max_transmission_unit = MTU; 61 if self.tx.available().is_some() {
76 caps.max_burst_size = Some(self.tx.len()); 62 Some(TxToken { tx: &mut self.tx })
77 caps 63 } else {
64 None
78 } 65 }
66 }
79 67
80 fn link_state(&mut self, cx: &mut Context) -> LinkState { 68 fn capabilities(&self) -> Capabilities {
81 // TODO: wake cx.waker on link state change 69 let mut caps = Capabilities::default();
82 cx.waker().wake_by_ref(); 70 caps.max_transmission_unit = MTU;
83 if P::poll_link(self) { 71 caps.max_burst_size = Some(self.tx.len());
84 LinkState::Up 72 caps
85 } else { 73 }
86 LinkState::Down
87 }
88 }
89 74
90 fn ethernet_address(&self) -> [u8; 6] { 75 fn link_state(&mut self, cx: &mut Context) -> LinkState {
91 self.mac_addr 76 // TODO: wake cx.waker on link state change
77 cx.waker().wake_by_ref();
78 if P::poll_link(self) {
79 LinkState::Up
80 } else {
81 LinkState::Down
92 } 82 }
93 } 83 }
94 84
95 pub struct RxToken<'a, 'd> { 85 fn ethernet_address(&self) -> [u8; 6] {
96 rx: &'a mut RDesRing<'d>, 86 self.mac_addr
97 } 87 }
88}
98 89
99 impl<'a, 'd> embassy_net::device::RxToken for RxToken<'a, 'd> { 90pub struct RxToken<'a, 'd> {
100 fn consume<R, F>(self, f: F) -> R 91 rx: &'a mut RDesRing<'d>,
101 where 92}
102 F: FnOnce(&mut [u8]) -> R,
103 {
104 // NOTE(unwrap): we checked the queue wasn't full when creating the token.
105 let pkt = unwrap!(self.rx.available());
106 let r = f(pkt);
107 self.rx.pop_packet();
108 r
109 }
110 }
111 93
112 pub struct TxToken<'a, 'd> { 94impl<'a, 'd> embassy_net_driver::RxToken for RxToken<'a, 'd> {
113 tx: &'a mut TDesRing<'d>, 95 fn consume<R, F>(self, f: F) -> R
96 where
97 F: FnOnce(&mut [u8]) -> R,
98 {
99 // NOTE(unwrap): we checked the queue wasn't full when creating the token.
100 let pkt = unwrap!(self.rx.available());
101 let r = f(pkt);
102 self.rx.pop_packet();
103 r
114 } 104 }
105}
115 106
116 impl<'a, 'd> embassy_net::device::TxToken for TxToken<'a, 'd> { 107pub struct TxToken<'a, 'd> {
117 fn consume<R, F>(self, len: usize, f: F) -> R 108 tx: &'a mut TDesRing<'d>,
118 where 109}
119 F: FnOnce(&mut [u8]) -> R, 110
120 { 111impl<'a, 'd> embassy_net_driver::TxToken for TxToken<'a, 'd> {
121 // NOTE(unwrap): we checked the queue wasn't full when creating the token. 112 fn consume<R, F>(self, len: usize, f: F) -> R
122 let pkt = unwrap!(self.tx.available()); 113 where
123 let r = f(&mut pkt[..len]); 114 F: FnOnce(&mut [u8]) -> R,
124 self.tx.transmit(len); 115 {
125 r 116 // NOTE(unwrap): we checked the queue wasn't full when creating the token.
126 } 117 let pkt = unwrap!(self.tx.available());
118 let r = f(&mut pkt[..len]);
119 self.tx.transmit(len);
120 r
127 } 121 }
128} 122}
123
129/// Station Management Interface (SMI) on an ethernet PHY 124/// Station Management Interface (SMI) on an ethernet PHY
130/// 125///
131/// # Safety 126/// # Safety
diff --git a/embassy-stm32/src/eth/v1/mod.rs b/embassy-stm32/src/eth/v1/mod.rs
index de36d3da1..9c0f4d66d 100644
--- a/embassy-stm32/src/eth/v1/mod.rs
+++ b/embassy-stm32/src/eth/v1/mod.rs
@@ -13,7 +13,7 @@ pub(crate) use self::rx_desc::{RDes, RDesRing};
13pub(crate) use self::tx_desc::{TDes, TDesRing}; 13pub(crate) use self::tx_desc::{TDes, TDesRing};
14use super::*; 14use super::*;
15use crate::gpio::sealed::{AFType, Pin as __GpioPin}; 15use crate::gpio::sealed::{AFType, Pin as __GpioPin};
16use crate::gpio::{AnyPin, Speed}; 16use crate::gpio::AnyPin;
17#[cfg(eth_v1a)] 17#[cfg(eth_v1a)]
18use crate::pac::AFIO; 18use crate::pac::AFIO;
19#[cfg(any(eth_v1b, eth_v1c))] 19#[cfg(any(eth_v1b, eth_v1c))]
@@ -66,7 +66,7 @@ macro_rules! config_pins {
66 critical_section::with(|_| { 66 critical_section::with(|_| {
67 $( 67 $(
68 $pin.set_as_af($pin.af_num(), AFType::OutputPushPull); 68 $pin.set_as_af($pin.af_num(), AFType::OutputPushPull);
69 $pin.set_speed(Speed::VeryHigh); 69 $pin.set_speed(crate::gpio::Speed::VeryHigh);
70 )* 70 )*
71 }) 71 })
72 }; 72 };