Skip to content

Commit 412afc4

Browse files
author
Johannes Draaijer
committed
Merge remote-tracking branch 'franeklubi/stm32f1' into 39-41-42
2 parents 3448d25 + 74bb39e commit 412afc4

File tree

15 files changed

+460
-70
lines changed

15 files changed

+460
-70
lines changed

.cargo/config

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ rustflags = [
44
"-C", "link-arg=-Tlink.x",
55
]
66

7+
[target.thumbv7m-none-eabi]
8+
runner = 'gdb'
9+
rustflags = [
10+
"-C", "link-arg=-Tlink.x",
11+
]
12+
713
[build]
814
# Pick ONE of these compilation targets
915
# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
language: rust
22
matrix:
33
include:
4+
- rust: nightly
5+
env: FEATURES='stm32f107'
46
- rust: nightly
57
env: FEATURES='stm32f407'
68
- rust: nightly
@@ -39,6 +41,6 @@ matrix:
3941
env: FEATURES='stm32f778'
4042
- rust: nightly
4143
env: FEATURES='stm32f779'
42-
44+
4345
script:
4446
- "cargo build --target=`uname -m`-unknown-linux-gnu --no-default-features --features \"$FEATURES\""

Cargo.toml

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

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

2020
[dependencies]
2121
volatile-register = "0.2"
2222
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}
23+
stm32f7xx-hal = { git = "https://github.com/stm32-rs/stm32f7xx-hal", rev = "d632a5c", optional = true }
24+
stm32f4xx-hal = { version = "0.10", optional = true }
25+
stm32f1xx-hal = { version = "0.9", optional = true }
2526
cortex-m = "0.7"
2627
log = { version = "0.4", optional = true }
2728

@@ -36,6 +37,8 @@ device-selected = []
3637
fence = []
3738
smi = []
3839

40+
stm32f107 = ["stm32f1xx-hal/stm32f107", "device-selected"]
41+
3942
stm32f407 = ["stm32f4xx-hal/stm32f407", "device-selected"]
4043
stm32f417 = ["stm32f4xx-hal/stm32f417", "device-selected"]
4144
stm32f427 = ["stm32f4xx-hal/stm32f427", "device-selected"]
@@ -59,10 +62,10 @@ smoltcp-phy = ["smoltcp"]
5962

6063
[dev-dependencies]
6164
cortex-m = "0.7"
62-
cortex-m-rt = ">=0.6.15, <0.8"
65+
cortex-m-rt = "0.7"
6366
panic-itm = "0.4"
64-
cortex-m-semihosting = "0.3.5"
65-
stm32f4xx-hal = {version = "0.10.1", features = ["rt"] }
67+
cortex-m-semihosting = "0.3"
68+
fugit = "0.3"
6669

6770
[[example]]
6871
name = "pktgen"
@@ -75,6 +78,13 @@ required-features = [
7578
"smoltcp/log", "smoltcp/verbose"
7679
]
7780

81+
[[example]]
82+
name = "ip-f107"
83+
required-features = [
84+
"stm32f107", "smoltcp-phy", "log", "smoltcp/socket-tcp", "smoltcp/socket-icmp",
85+
"smoltcp/log", "smoltcp/verbose"
86+
]
87+
7888
[[example]]
7989
name = "arp"
8090
required-features = ["stm32f407", "smi"]

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,38 @@
44

55
## Supported microcontrollers
66

7+
* STM32F107
78
* STM32F4xx
89
* STM32F7xx
910

1011
Please send pull requests.
1112

1213
## Building Examples
13-
```
14+
15+
```bash
1416
cargo build --example="pktgen" --features="stm32f429"
1517
cargo build --example="ip" --features="stm32f429 smoltcp-phy log smoltcp/socket-tcp smoltcp/socket-icmp smoltcp/log smoltcp/verbose"
18+
cargo build --example="ip-f107" --features="stm32f107 smoltcp-phy log smoltcp/socket-tcp smoltcp/socket-icmp smoltcp/log smoltcp/verbose"
1619
```
1720

1821
## Usage
1922

2023
Add to the `[dependencies]` section in your `Cargo.toml`:
24+
2125
```rust
2226
stm32f4xx-hal = { version = "0.10.1", features = ["stm32f429"] }
2327
stm32-eth = { version = "0.2.0", features = ["stm32f429"] }
2428
```
29+
2530
or
31+
2632
```rust
2733
stm32f7xx-hal = { version = "0.6.0", features = ["stm32f767"] }
2834
stm32-eth = { version = "0.2.0", features = ["stm32f767"]}
2935
```
3036

3137
In `src/main.rs` add:
38+
3239
```rust
3340
use stm32_eth::{
3441
hal::gpio::GpioExt,

examples/arp-smoltcp.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,19 @@ extern crate panic_itm;
1212

1313
use core::cell::RefCell;
1414
use core::default::Default;
15-
use cortex_m_rt::{entry, exception};
1615

1716
use cortex_m::asm;
1817
use cortex_m::interrupt::Mutex;
18+
use cortex_m_rt::{entry, exception};
19+
use cortex_m_semihosting::hprintln;
20+
use fugit::RateExtU32;
21+
use smoltcp::wire::{
22+
ArpOperation, ArpPacket, ArpRepr, EthernetAddress, EthernetFrame, EthernetProtocol,
23+
EthernetRepr, Ipv4Address,
24+
};
1925
use stm32_eth::{
2026
hal::gpio::{GpioExt, Speed},
2127
hal::rcc::RccExt,
22-
hal::time::U32Ext,
2328
smi,
2429
stm32::{interrupt, CorePeripherals, Peripherals, SYST},
2530
};
@@ -30,7 +35,7 @@ use smoltcp::wire::{
3035
ArpOperation, ArpPacket, ArpRepr, EthernetAddress, EthernetFrame, EthernetProtocol,
3136
EthernetRepr, Ipv4Address,
3237
};
33-
use stm32_eth::{EthPins, RingEntry, TxError};
38+
use stm32_eth::{Eth, EthPins, RingEntry, TxError};
3439

3540
const PHY_REG_BSR: u8 = 0x01;
3641
const PHY_REG_BSR_UP: u16 = 1 << 2;
@@ -47,7 +52,7 @@ fn main() -> ! {
4752

4853
let rcc = p.RCC.constrain();
4954
// HCLK must be at least 25MHz to use the ethernet peripheral
50-
let clocks = rcc.cfgr.sysclk(32.mhz()).hclk(32.mhz()).freeze();
55+
let clocks = rcc.cfgr.sysclk(32.MHz()).hclk(32.MHz()).freeze();
5156

5257
setup_systick(&mut cp.SYST);
5358

examples/arp.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ use cortex_m_rt::{entry, exception};
1616

1717
use cortex_m::asm;
1818
use cortex_m::interrupt::Mutex;
19+
use fugit::RateExtU32;
1920
use stm32_eth::{
2021
hal::gpio::{GpioExt, Speed},
2122
hal::rcc::RccExt,
22-
hal::time::U32Ext,
2323
smi,
2424
stm32::{interrupt, CorePeripherals, Peripherals, SYST},
2525
};
@@ -43,7 +43,7 @@ fn main() -> ! {
4343

4444
let rcc = p.RCC.constrain();
4545
// HCLK must be at least 25MHz to use the ethernet peripheral
46-
let clocks = rcc.cfgr.sysclk(32.mhz()).hclk(32.mhz()).freeze();
46+
let clocks = rcc.cfgr.sysclk(32.MHz()).hclk(32.MHz()).freeze();
4747

4848
setup_systick(&mut cp.SYST);
4949

examples/ip-f107.rs

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
// A copy of the `ip.rs` example, but for the STM32F107.
2+
3+
#![no_std]
4+
#![no_main]
5+
6+
extern crate panic_itm;
7+
8+
use cortex_m::asm;
9+
use cortex_m_rt::{entry, exception};
10+
use stm32_eth::{
11+
hal::flash::FlashExt,
12+
hal::gpio::GpioExt,
13+
hal::rcc::RccExt,
14+
stm32::{interrupt, CorePeripherals, Peripherals, SYST},
15+
};
16+
17+
use core::cell::RefCell;
18+
use cortex_m::interrupt::Mutex;
19+
20+
use core::fmt::Write;
21+
use cortex_m_semihosting::hio;
22+
23+
use fugit::RateExtU32;
24+
use log::{Level, LevelFilter, Metadata, Record};
25+
use smoltcp::iface::{InterfaceBuilder, NeighborCache};
26+
use smoltcp::socket::{TcpSocket, TcpSocketBuffer};
27+
use smoltcp::time::Instant;
28+
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address};
29+
30+
use stm32_eth::{Eth, EthPins, RingEntry};
31+
32+
static mut LOGGER: HioLogger = HioLogger {};
33+
34+
struct HioLogger {}
35+
36+
impl log::Log for HioLogger {
37+
fn enabled(&self, metadata: &Metadata) -> bool {
38+
metadata.level() <= Level::Trace
39+
}
40+
41+
fn log(&self, record: &Record) {
42+
if self.enabled(record.metadata()) {
43+
let mut stdout = hio::hstdout().unwrap();
44+
writeln!(stdout, "{} - {}", record.level(), record.args()).unwrap();
45+
}
46+
}
47+
fn flush(&self) {}
48+
}
49+
50+
const SRC_MAC: [u8; 6] = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
51+
52+
static TIME: Mutex<RefCell<u64>> = Mutex::new(RefCell::new(0));
53+
static ETH_PENDING: Mutex<RefCell<bool>> = Mutex::new(RefCell::new(false));
54+
55+
#[entry]
56+
fn main() -> ! {
57+
unsafe {
58+
log::set_logger(&LOGGER).unwrap();
59+
}
60+
log::set_max_level(LevelFilter::Info);
61+
62+
let mut stdout = hio::hstdout().unwrap();
63+
64+
let p = Peripherals::take().unwrap();
65+
let mut cp = CorePeripherals::take().unwrap();
66+
67+
let mut flash = p.FLASH.constrain();
68+
69+
let rcc = p.RCC.constrain();
70+
// HCLK must be at least 25MHz to use the ethernet peripheral
71+
let clocks = rcc
72+
.cfgr
73+
.sysclk(32.MHz())
74+
.hclk(32.MHz())
75+
.freeze(&mut flash.acr);
76+
77+
setup_systick(&mut cp.SYST);
78+
79+
writeln!(stdout, "Enabling ethernet...").unwrap();
80+
81+
let mut gpioa = p.GPIOA.split();
82+
let mut gpiob = p.GPIOB.split();
83+
let mut gpioc = p.GPIOC.split();
84+
85+
// PLL3CLK goes to MCO (Main Clock Output) (PA8)
86+
let _mco = gpioa.pa8.into_alternate_push_pull(&mut gpioa.crh);
87+
88+
let ref_clk = gpioa.pa1.into_floating_input(&mut gpioa.crl);
89+
let crs = gpioa.pa7.into_floating_input(&mut gpioa.crl);
90+
let tx_en = gpiob.pb11.into_alternate_push_pull(&mut gpiob.crh);
91+
let tx_d0 = gpiob.pb12.into_alternate_push_pull(&mut gpiob.crh);
92+
let tx_d1 = gpiob.pb13.into_alternate_push_pull(&mut gpiob.crh);
93+
let rx_d0 = gpioc.pc4.into_floating_input(&mut gpioc.crl);
94+
let rx_d1 = gpioc.pc5.into_floating_input(&mut gpioc.crl);
95+
96+
let eth_pins = EthPins {
97+
ref_clk,
98+
crs,
99+
tx_en,
100+
tx_d0,
101+
tx_d1,
102+
rx_d0,
103+
rx_d1,
104+
};
105+
106+
let mut rx_ring: [RingEntry<_>; 8] = Default::default();
107+
let mut tx_ring: [RingEntry<_>; 2] = Default::default();
108+
let mut eth = Eth::new(
109+
p.ETHERNET_MAC,
110+
p.ETHERNET_DMA,
111+
&mut rx_ring[..],
112+
&mut tx_ring[..],
113+
clocks,
114+
eth_pins,
115+
)
116+
.unwrap();
117+
eth.enable_interrupt();
118+
119+
let local_addr = Ipv4Address::new(10, 0, 0, 1);
120+
let ip_addr = IpCidr::new(IpAddress::from(local_addr), 24);
121+
let mut ip_addrs = [ip_addr];
122+
let mut neighbor_storage = [None; 16];
123+
let neighbor_cache = NeighborCache::new(&mut neighbor_storage[..]);
124+
let ethernet_addr = EthernetAddress(SRC_MAC);
125+
126+
let mut sockets: [_; 1] = Default::default();
127+
let mut iface = InterfaceBuilder::new(&mut eth, &mut sockets[..])
128+
.hardware_addr(ethernet_addr.into())
129+
.ip_addrs(&mut ip_addrs[..])
130+
.neighbor_cache(neighbor_cache)
131+
.finalize();
132+
133+
let mut server_rx_buffer = [0; 2048];
134+
let mut server_tx_buffer = [0; 2048];
135+
let server_socket = TcpSocket::new(
136+
TcpSocketBuffer::new(&mut server_rx_buffer[..]),
137+
TcpSocketBuffer::new(&mut server_tx_buffer[..]),
138+
);
139+
let server_handle = iface.add_socket(server_socket);
140+
141+
writeln!(stdout, "Ready, listening at {}", ip_addr).unwrap();
142+
loop {
143+
let time: u64 = cortex_m::interrupt::free(|cs| *TIME.borrow(cs).borrow());
144+
cortex_m::interrupt::free(|cs| {
145+
let mut eth_pending = ETH_PENDING.borrow(cs).borrow_mut();
146+
*eth_pending = false;
147+
});
148+
match iface.poll(Instant::from_millis(time as i64)) {
149+
Ok(true) => {
150+
let socket = iface.get_socket::<TcpSocket>(server_handle);
151+
if !socket.is_open() {
152+
socket
153+
.listen(80)
154+
.or_else(|e| writeln!(stdout, "TCP listen error: {:?}", e))
155+
.unwrap();
156+
}
157+
158+
if socket.can_send() {
159+
write!(socket, "hello\n")
160+
.map(|_| {
161+
socket.close();
162+
})
163+
.or_else(|e| writeln!(stdout, "TCP send error: {:?}", e))
164+
.unwrap();
165+
}
166+
}
167+
Ok(false) => {
168+
// Sleep if no ethernet work is pending
169+
cortex_m::interrupt::free(|cs| {
170+
let eth_pending = ETH_PENDING.borrow(cs).borrow_mut();
171+
if !*eth_pending {
172+
asm::wfi();
173+
// Awaken by interrupt
174+
}
175+
});
176+
}
177+
Err(e) =>
178+
// Ignore malformed packets
179+
{
180+
writeln!(stdout, "Error: {:?}", e).unwrap()
181+
}
182+
}
183+
}
184+
}
185+
186+
fn setup_systick(syst: &mut SYST) {
187+
syst.set_reload(SYST::get_ticks_per_10ms() / 10);
188+
syst.enable_counter();
189+
syst.enable_interrupt();
190+
}
191+
192+
#[exception]
193+
fn SysTick() {
194+
cortex_m::interrupt::free(|cs| {
195+
let mut time = TIME.borrow(cs).borrow_mut();
196+
*time += 1;
197+
})
198+
}
199+
200+
#[interrupt]
201+
fn ETH() {
202+
cortex_m::interrupt::free(|cs| {
203+
let mut eth_pending = ETH_PENDING.borrow(cs).borrow_mut();
204+
*eth_pending = true;
205+
});
206+
207+
// Clear interrupt flags
208+
let p = unsafe { Peripherals::steal() };
209+
stm32_eth::eth_interrupt_handler(&p.ETHERNET_DMA);
210+
}

0 commit comments

Comments
 (0)