aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordvdsk <[email protected]>2024-06-07 23:46:59 +0200
committerdvdsk <[email protected]>2024-06-07 23:46:59 +0200
commit1812ccd276a6c277e7c99191c0aa5ce3d1c90e84 (patch)
tree14187edbb0859b1352eff648547e1ea3ea7de131
parent72c2b06520a2e25e180df6d89d5b3b39a8380f0c (diff)
Adds an example for using the w5500 with an stm32f4
This example takes into account the lower memory on the stm32f4. That should prevent anyone wanting to use the w5500 on any stm from adapting the w5500 example for the rp which uses a lot more RAM.
-rw-r--r--examples/stm32f4/Cargo.toml2
-rw-r--r--examples/stm32f4/src/bin/eth_w5500.rs139
2 files changed, 141 insertions, 0 deletions
diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml
index 52b7ce9e8..11cb4cb3c 100644
--- a/examples/stm32f4/Cargo.toml
+++ b/examples/stm32f4/Cargo.toml
@@ -12,6 +12,7 @@ embassy-executor = { version = "0.5.0", path = "../../embassy-executor", feature
12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } 12embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
13embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt" ] } 13embassy-usb = { version = "0.2.0", path = "../../embassy-usb", features = ["defmt" ] }
14embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] } 14embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] }
15embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] }
15embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 16embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
16 17
17defmt = "0.3" 18defmt = "0.3"
@@ -20,6 +21,7 @@ defmt-rtt = "0.4"
20cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } 21cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
21cortex-m-rt = "0.7.0" 22cortex-m-rt = "0.7.0"
22embedded-hal = "0.2.6" 23embedded-hal = "0.2.6"
24embedded-hal-bus = { version = "0.2", features = ["async"] }
23embedded-io = { version = "0.6.0" } 25embedded-io = { version = "0.6.0" }
24embedded-io-async = { version = "0.6.1" } 26embedded-io-async = { version = "0.6.1" }
25panic-probe = { version = "0.3", features = ["print-defmt"] } 27panic-probe = { version = "0.3", features = ["print-defmt"] }
diff --git a/examples/stm32f4/src/bin/eth_w5500.rs b/examples/stm32f4/src/bin/eth_w5500.rs
new file mode 100644
index 000000000..827e74c51
--- /dev/null
+++ b/examples/stm32f4/src/bin/eth_w5500.rs
@@ -0,0 +1,139 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_net::tcp::TcpSocket;
7use embassy_net::{Ipv4Address, Stack, StackResources};
8use embassy_net_wiznet::{chip::W5500, Device, Runner, State};
9use embassy_stm32::gpio::{Level, Output, Pull, Speed};
10use embassy_stm32::exti::ExtiInput;
11use embassy_stm32::rng::Rng;
12use embassy_stm32::spi::Spi;
13use embassy_stm32::mode::Async;
14use embassy_stm32::time::Hertz;
15use embassy_stm32::{bind_interrupts, peripherals, rng, spi, Config};
16use embassy_time::{Timer, Delay};
17use embedded_io_async::Write;
18use embedded_hal_bus::spi::ExclusiveDevice;
19use static_cell::StaticCell;
20use {defmt_rtt as _, panic_probe as _};
21
22bind_interrupts!(struct Irqs {
23 HASH_RNG => rng::InterruptHandler<peripherals::RNG>;
24});
25
26type EthernetSPI = ExclusiveDevice<Spi<'static, Async>, Output<'static>, Delay>;
27#[embassy_executor::task]
28async fn ethernet_task(
29 runner: Runner<'static, W5500, EthernetSPI, ExtiInput<'static>, Output<'static>>,
30) -> ! {
31 runner.run().await
32}
33
34#[embassy_executor::task]
35async fn net_task(stack: &'static Stack<Device<'static>>) -> ! {
36 stack.run().await
37}
38
39#[embassy_executor::main]
40async fn main(spawner: Spawner) -> ! {
41 let mut config = Config::default();
42 {
43 use embassy_stm32::rcc::*;
44 config.rcc.hse = Some(Hse {
45 freq: Hertz(8_000_000),
46 mode: HseMode::Bypass,
47 });
48 config.rcc.pll_src = PllSource::HSE;
49 config.rcc.pll = Some(Pll {
50 prediv: PllPreDiv::DIV4,
51 mul: PllMul::MUL180,
52 divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 180 / 2 = 180Mhz.
53 divq: None,
54 divr: None,
55 });
56 config.rcc.ahb_pre = AHBPrescaler::DIV1;
57 config.rcc.apb1_pre = APBPrescaler::DIV4;
58 config.rcc.apb2_pre = APBPrescaler::DIV2;
59 config.rcc.sys = Sysclk::PLL1_P;
60 }
61 let p = embassy_stm32::init(config);
62
63 info!("Hello World!");
64
65 // Generate random seed
66 let mut rng = Rng::new(p.RNG, Irqs);
67 let mut seed = [0; 8];
68 unwrap!(rng.async_fill_bytes(&mut seed).await);
69 let seed = u64::from_le_bytes(seed);
70
71 let mut spi_cfg = spi::Config::default();
72 spi_cfg.frequency = Hertz(50_000_000); // up to 50m works
73 let (miso, mosi, clk) = (p.PA6, p.PA7, p.PA5);
74 let spi = Spi::new(p.SPI1, clk, mosi, miso, p.DMA2_CH3, p.DMA2_CH0, spi_cfg);
75 let cs = Output::new(p.PA4, Level::High, Speed::VeryHigh);
76 let spi = unwrap!(ExclusiveDevice::new(spi, cs, Delay));
77
78 let w5500_int = ExtiInput::new(p.PB0, p.EXTI0, Pull::Up);
79 let w5500_reset = Output::new(p.PB1, Level::High, Speed::VeryHigh);
80
81 let mac_addr = [0x02, 234, 3, 4, 82, 231];
82 static STATE: StaticCell<State<2, 2>> = StaticCell::new();
83 let state = STATE.init(State::<2, 2>::new());
84 let (device, runner) = embassy_net_wiznet::new(mac_addr, state, spi, w5500_int, w5500_reset).await;
85 unwrap!(spawner.spawn(ethernet_task(runner)));
86
87 let config = embassy_net::Config::dhcpv4(Default::default());
88 //let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 {
89 // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24),
90 // dns_servers: Vec::new(),
91 // gateway: Some(Ipv4Address::new(10, 42, 0, 1)),
92 //});
93
94 static STACK: StaticCell<Stack<Device>> = StaticCell::new();
95 static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new();
96 let stack = &*STACK.init(Stack::new(
97 device,
98 config,
99 RESOURCES.init(StackResources::<2>::new()),
100 seed,
101 ));
102
103 // Launch network task
104 unwrap!(spawner.spawn(net_task(stack)));
105
106 // Ensure DHCP configuration is up before trying connect
107 stack.wait_config_up().await;
108
109 info!("Network task initialized");
110
111 // Then we can use it!
112 let mut rx_buffer = [0; 1024];
113 let mut tx_buffer = [0; 1024];
114
115 loop {
116 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
117
118 socket.set_timeout(Some(embassy_time::Duration::from_secs(10)));
119
120 let remote_endpoint = (Ipv4Address::new(10, 42, 0, 1), 8000);
121 info!("connecting...");
122 let r = socket.connect(remote_endpoint).await;
123 if let Err(e) = r {
124 info!("connect error: {:?}", e);
125 Timer::after_secs(1).await;
126 continue;
127 }
128 info!("connected!");
129 let buf = [0; 1024];
130 loop {
131 let r = socket.write_all(&buf).await;
132 if let Err(e) = r {
133 info!("write error: {:?}", e);
134 break;
135 }
136 Timer::after_secs(1).await;
137 }
138 }
139}