Skip to content

Commit f246fae

Browse files
authored
Merge pull request #37 from systec-ms/smoltcp-0.8
Bump smoltcp from 0.7 to 0.8
2 parents 0ab4556 + 71d6363 commit f246fae

File tree

12 files changed

+234
-354
lines changed

12 files changed

+234
-354
lines changed

Cargo.toml

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,26 @@ travis-ci = { repository = "astro/stm32-eth", branch = "master" }
1515
maintenance = { status = "experimental" }
1616

1717
[package.metadata.docs.rs]
18-
features = [ "smoltcp-phy", "stm32f429" ]
18+
features = [ "smi", "smoltcp-phy", "stm32f429" ]
1919

2020
[dependencies]
2121
volatile-register = "0.2"
22-
aligned = "0.3"
23-
stm32f7xx-hal = {version = "0.2.0", optional = true}
24-
stm32f4xx-hal = {version = "0.8.3", optional = true}
25-
cortex-m = "0.6.2"
22+
aligned = "0.4"
23+
stm32f7xx-hal = {git = "https://github.com/stm32-rs/stm32f7xx-hal", rev = "d632a5c", optional = true}
24+
stm32f4xx-hal = {version = "0.10", optional = true}
25+
cortex-m = "0.7"
2626
log = { version = "0.4", optional = true }
2727

2828
[dependencies.smoltcp]
29-
version = "0.7.0"
29+
version = "0.8"
3030
default-features = false
31-
features = ["ethernet", "proto-ipv4"]
31+
features = ["medium-ethernet", "proto-ipv4"]
3232
optional = true
3333

3434
[features]
3535
device-selected = []
3636
fence = []
37+
smi = []
3738

3839
stm32f407 = ["stm32f4xx-hal/stm32f407", "device-selected"]
3940
stm32f417 = ["stm32f4xx-hal/stm32f417", "device-selected"]
@@ -57,15 +58,15 @@ stm32f779 = ["stm32f7xx-hal/stm32f779", "device-selected", "fence"]
5758
smoltcp-phy = ["smoltcp"]
5859

5960
[dev-dependencies]
60-
cortex-m = "0.6.2"
61-
cortex-m-rt = "0.6"
61+
cortex-m = "0.7"
62+
cortex-m-rt = ">=0.6.15, <0.8"
6263
panic-itm = "0.4"
6364
cortex-m-semihosting = "0.3.5"
64-
stm32f4xx-hal = {version = "0.8.3", features = ["rt"] }
65+
stm32f4xx-hal = {version = "0.10.1", features = ["rt"] }
6566

6667
[[example]]
6768
name = "pktgen"
68-
required-features = ["stm32f429"]
69+
required-features = ["smi", "stm32f429"]
6970

7071
[[example]]
7172
name = "ip"
@@ -74,9 +75,13 @@ required-features = [
7475
"smoltcp/log", "smoltcp/verbose"
7576
]
7677

78+
[[example]]
79+
name = "arp"
80+
required-features = ["stm32f407", "smi"]
81+
7782
[[example]]
7883
name = "arp-smoltcp"
79-
required-features = ["stm32f429", "smoltcp-phy"]
84+
required-features = ["stm32f407", "smi", "smoltcp-phy", "smoltcp/socket-icmp"]
8085

8186
[profile.release]
8287
debug = 2

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ cargo build --example="ip" --features="stm32f429 smoltcp-phy log smoltcp/socket-
1919

2020
Add to the `[dependencies]` section in your `Cargo.toml`:
2121
```rust
22-
stm32f4xx-hal = { version = "0.8.3", features = ["stm32f429"] }
22+
stm32f4xx-hal = { version = "0.10.1", features = ["stm32f429"] }
2323
stm32-eth = { version = "0.2.0", features = ["stm32f429"] }
2424
```
2525
or
2626
```rust
27-
stm32f7xx-hal = { version = "0.2.0", features = ["stm32f767"] }
27+
stm32f7xx-hal = { version = "0.6.0", features = ["stm32f767"] }
2828
stm32-eth = { version = "0.2.0", features = ["stm32f767"]}
2929
```
3030

@@ -70,7 +70,6 @@ fn main() {
7070
p.ETHERNET_DMA,
7171
&mut rx_ring[..],
7272
&mut tx_ring[..],
73-
PhyAddress::_0,
7473
clocks,
7574
eth_pins,
7675
)

examples/arp-smoltcp.rs

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
// cargo build --example arp-smoltcp --features=stm32f407,smi,smoltcp-phy,smoltcp/socket-tcp,smoltcp/socket-icmp
2+
// This example uses the STM32F407 and the KSZ8051R as PHY. If necessary the pins,
3+
// the PHY register addresses and masks have to be adapted, as well as the IPs.
4+
// With Wireshark, you can see the ARP packets, which should look like this:
5+
// No. Time Source Destination Protocol Length Info
6+
// 1 0.000000000 Cetia_ad:be:ef Broadcast ARP 60 Who has 10.0.0.2? Tell 10.0.0.10
7+
18
#![no_std]
29
#![no_main]
310

@@ -10,9 +17,10 @@ use cortex_m_rt::{entry, exception};
1017
use cortex_m::asm;
1118
use cortex_m::interrupt::Mutex;
1219
use stm32_eth::{
13-
hal::gpio::GpioExt,
20+
hal::gpio::{GpioExt, Speed},
1421
hal::rcc::RccExt,
1522
hal::time::U32Ext,
23+
smi,
1624
stm32::{interrupt, CorePeripherals, Peripherals, SYST},
1725
};
1826

@@ -22,7 +30,12 @@ use smoltcp::wire::{
2230
ArpOperation, ArpPacket, ArpRepr, EthernetAddress, EthernetFrame, EthernetProtocol,
2331
EthernetRepr, Ipv4Address,
2432
};
25-
use stm32_eth::{Eth, EthPins, PhyAddress, RingEntry, TxError};
33+
use stm32_eth::{Eth, EthPins, RingEntry, TxError};
34+
35+
const PHY_REG_BSR: u8 = 0x01;
36+
const PHY_REG_BSR_UP: u16 = 1 << 2;
37+
38+
const PHY_ADDR: u8 = 0;
2639

2740
static TIME: Mutex<RefCell<usize>> = Mutex::new(RefCell::new(0));
2841
static ETH_PENDING: Mutex<RefCell<bool>> = Mutex::new(RefCell::new(false));
@@ -42,62 +55,52 @@ fn main() -> ! {
4255
let gpioa = p.GPIOA.split();
4356
let gpiob = p.GPIOB.split();
4457
let gpioc = p.GPIOC.split();
45-
// let gpiog = p.GPIOG.split();
58+
let gpiog = p.GPIOG.split();
4659

4760
let eth_pins = EthPins {
4861
ref_clk: gpioa.pa1,
49-
md_io: gpioa.pa2,
50-
md_clk: gpioc.pc1,
5162
crs: gpioa.pa7,
5263
tx_en: gpiob.pb11,
53-
tx_d0: gpiob.pb12,
54-
tx_d1: gpiob.pb13,
64+
tx_d0: gpiog.pg13,
65+
tx_d1: gpiog.pg14,
5566
rx_d0: gpioc.pc4,
5667
rx_d1: gpioc.pc5,
5768
};
5869

70+
let mut mdio = gpioa.pa2.into_alternate().set_speed(Speed::VeryHigh);
71+
let mut mdc = gpioc.pc1.into_alternate().set_speed(Speed::VeryHigh);
72+
73+
// ETH_PHY_RESET(RST#) PB2 Chip Reset (active-low)
74+
let _eth_reset = gpiob.pb2.into_push_pull_output().set_high();
75+
5976
let mut rx_ring: [RingEntry<_>; 16] = Default::default();
6077
let mut tx_ring: [RingEntry<_>; 8] = Default::default();
6178
let mut eth = Eth::new(
6279
p.ETHERNET_MAC,
6380
p.ETHERNET_DMA,
6481
&mut rx_ring[..],
6582
&mut tx_ring[..],
66-
PhyAddress::_1,
6783
clocks,
6884
eth_pins,
6985
)
7086
.unwrap();
7187
eth.enable_interrupt();
7288

73-
let mut last_status = None;
89+
let mut last_link_up = false;
7490

7591
loop {
76-
let status = eth.status();
92+
let link_up = link_detected(eth.smi(&mut mdio, &mut mdc));
7793

78-
if last_status
79-
.map(|last_status| last_status != status)
80-
.unwrap_or(true)
81-
{
82-
if !status.link_detected() {
83-
hprintln!("Ethernet: no link detected").unwrap();
94+
if link_up != last_link_up {
95+
if link_up {
96+
hprintln!("Ethernet: link detected").unwrap();
8497
} else {
85-
hprintln!(
86-
"Ethernet: link detected with {} Mbps/{}",
87-
status.speed(),
88-
match status.is_full_duplex() {
89-
Some(true) => "FD",
90-
Some(false) => "HD",
91-
None => "?",
92-
}
93-
)
94-
.unwrap();
98+
hprintln!("Ethernet: no link detected").unwrap();
9599
}
96-
97-
last_status = Some(status);
100+
last_link_up = link_up;
98101
}
99102

100-
if status.link_detected() {
103+
if link_up {
101104
const SIZE: usize = 14 + 28; // ETH + ARP
102105

103106
let src_mac = EthernetAddress::from_bytes(&[0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]);
@@ -108,9 +111,9 @@ fn main() -> ! {
108111
let arp = ArpRepr::EthernetIpv4 {
109112
operation: ArpOperation::Request,
110113
source_hardware_addr: src_mac,
111-
source_protocol_addr: Ipv4Address::new(192, 168, 1, 100),
114+
source_protocol_addr: Ipv4Address::new(10, 0, 0, 10),
112115
target_hardware_addr: EthernetAddress::from_bytes(&[0x00; 6]),
113-
target_protocol_addr: Ipv4Address::new(192, 168, 1, 254),
116+
target_protocol_addr: Ipv4Address::new(10, 0, 0, 2),
114117
};
115118
arp.emit(&mut packet);
116119

@@ -175,3 +178,12 @@ fn ETH() {
175178
let p = unsafe { Peripherals::steal() };
176179
stm32_eth::eth_interrupt_handler(&p.ETHERNET_DMA);
177180
}
181+
182+
fn link_detected<Mdio, Mdc>(smi: smi::Smi<Mdio, Mdc>) -> bool
183+
where
184+
Mdio: smi::MdioPin,
185+
Mdc: smi::MdcPin,
186+
{
187+
let status = smi.read(PHY_ADDR, PHY_REG_BSR);
188+
(status & PHY_REG_BSR_UP) == PHY_REG_BSR_UP
189+
}

examples/arp.rs

Lines changed: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
// cargo build --example arp --features=stm32f407,smi
2+
// This example uses the STM32F407 and the KSZ8051R as PHY. If necessary the pins,
3+
// the PHY register addresses and masks have to be adapted, as well as the IPs.
4+
// With Wireshark, you can see the ARP packets, which should look like this:
5+
// No. Time Source Destination Protocol Length Info
6+
// 1 0.000000000 Cetia_ad:be:ef Broadcast ARP 60 Who has 10.0.0.2? Tell 10.0.0.10
7+
18
#![no_std]
29
#![no_main]
310

@@ -10,15 +17,21 @@ use cortex_m_rt::{entry, exception};
1017
use cortex_m::asm;
1118
use cortex_m::interrupt::Mutex;
1219
use stm32_eth::{
13-
hal::gpio::GpioExt,
20+
hal::gpio::{GpioExt, Speed},
1421
hal::rcc::RccExt,
1522
hal::time::U32Ext,
23+
smi,
1624
stm32::{interrupt, CorePeripherals, Peripherals, SYST},
1725
};
1826

1927
use cortex_m_semihosting::hprintln;
2028

21-
use stm32_eth::{Eth, EthPins, PhyAddress, RingEntry, TxError};
29+
use stm32_eth::{Eth, EthPins, RingEntry, TxError};
30+
31+
const PHY_REG_BSR: u8 = 0x01;
32+
const PHY_REG_BSR_UP: u16 = 1 << 2;
33+
34+
const PHY_ADDR: u8 = 0;
2235

2336
static TIME: Mutex<RefCell<usize>> = Mutex::new(RefCell::new(0));
2437
static ETH_PENDING: Mutex<RefCell<bool>> = Mutex::new(RefCell::new(false));
@@ -38,75 +51,65 @@ fn main() -> ! {
3851
let gpioa = p.GPIOA.split();
3952
let gpiob = p.GPIOB.split();
4053
let gpioc = p.GPIOC.split();
41-
// let gpiog = p.GPIOG.split();
54+
let gpiog = p.GPIOG.split();
4255

4356
let eth_pins = EthPins {
4457
ref_clk: gpioa.pa1,
45-
md_io: gpioa.pa2,
46-
md_clk: gpioc.pc1,
4758
crs: gpioa.pa7,
4859
tx_en: gpiob.pb11,
49-
tx_d0: gpiob.pb12,
50-
tx_d1: gpiob.pb13,
60+
tx_d0: gpiog.pg13,
61+
tx_d1: gpiog.pg14,
5162
rx_d0: gpioc.pc4,
5263
rx_d1: gpioc.pc5,
5364
};
5465

66+
let mut mdio = gpioa.pa2.into_alternate().set_speed(Speed::VeryHigh);
67+
let mut mdc = gpioc.pc1.into_alternate().set_speed(Speed::VeryHigh);
68+
69+
// ETH_PHY_RESET(RST#) PB2 Chip Reset (active-low)
70+
let _eth_reset = gpiob.pb2.into_push_pull_output().set_high();
71+
5572
let mut rx_ring: [RingEntry<_>; 16] = Default::default();
5673
let mut tx_ring: [RingEntry<_>; 8] = Default::default();
5774
let mut eth = Eth::new(
5875
p.ETHERNET_MAC,
5976
p.ETHERNET_DMA,
6077
&mut rx_ring[..],
6178
&mut tx_ring[..],
62-
PhyAddress::_1,
6379
clocks,
6480
eth_pins,
6581
)
6682
.unwrap();
6783
eth.enable_interrupt();
6884

69-
let mut last_status = None;
85+
let mut last_link_up = false;
7086

7187
loop {
72-
let status = eth.status();
88+
let link_up = link_detected(eth.smi(&mut mdio, &mut mdc));
7389

74-
if last_status
75-
.map(|last_status| last_status != status)
76-
.unwrap_or(true)
77-
{
78-
if !status.link_detected() {
79-
hprintln!("Ethernet: no link detected").unwrap();
90+
if link_up != last_link_up {
91+
if link_up {
92+
hprintln!("Ethernet: link detected").unwrap();
8093
} else {
81-
hprintln!(
82-
"Ethernet: link detected with {} Mbps/{}",
83-
status.speed(),
84-
match status.is_full_duplex() {
85-
Some(true) => "FD",
86-
Some(false) => "HD",
87-
None => "?",
88-
}
89-
)
90-
.unwrap();
94+
hprintln!("Ethernet: no link detected").unwrap();
9195
}
92-
93-
last_status = Some(status);
96+
last_link_up = link_up;
9497
}
9598

96-
if status.link_detected() {
99+
if link_up {
97100
const SIZE: usize = 42;
98101

99102
const DST_MAC: [u8; 6] = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF];
100103
const SRC_MAC: [u8; 6] = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
101104
const ETH_TYPE: [u8; 2] = [0x08, 0x06]; // ARP
102-
const HTYPE: [u8; 2] = [0x00, 0x01];
105+
const HTYPE: [u8; 2] = [0x00, 0x01]; // Hardware Type: ethernet
103106
const PTYPE: [u8; 2] = [0x08, 0x00]; // IP
104107
const HLEN: [u8; 1] = [0x06]; // MAC length
105108
const PLEN: [u8; 1] = [0x04]; // IPv4
106-
const OPER: [u8; 2] = [0x00, 0x01];
107-
const SENDER_IP: [u8; 4] = [0xc0, 0xa8, 0x01, 0x64]; // 192.168.1.100
109+
const OPER: [u8; 2] = [0x00, 0x01]; // Operation: request
110+
const SENDER_IP: [u8; 4] = [0x0A, 00, 0x00, 0x0A]; // 10.0.0.10
108111
const TARGET_MAC: [u8; 6] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
109-
const TARGET_IP: [u8; 4] = [0xc0, 0xa8, 0x01, 0xFE];
112+
const TARGET_IP: [u8; 4] = [0x0A, 0x00, 0x00, 0x02]; // 10.0.0.2
110113

111114
let r = eth.send(SIZE, |buf| {
112115
buf[0..6].copy_from_slice(&DST_MAC);
@@ -171,3 +174,12 @@ fn ETH() {
171174
let p = unsafe { Peripherals::steal() };
172175
stm32_eth::eth_interrupt_handler(&p.ETHERNET_DMA);
173176
}
177+
178+
fn link_detected<Mdio, Mdc>(smi: smi::Smi<Mdio, Mdc>) -> bool
179+
where
180+
Mdio: smi::MdioPin,
181+
Mdc: smi::MdcPin,
182+
{
183+
let status = smi.read(PHY_ADDR, PHY_REG_BSR);
184+
(status & PHY_REG_BSR_UP) == PHY_REG_BSR_UP
185+
}

0 commit comments

Comments
 (0)