summaryrefslogtreecommitdiff
path: root/examples/stm32f7
diff options
context:
space:
mode:
authorMatous Hybl <hyblmatous@gmail.com>2021-10-28 14:22:02 +0200
committerMatous Hybl <hyblmatous@gmail.com>2021-11-10 10:16:46 +0100
commitf0ba79059eea9a2c4f946d86e9e78136bdf99790 (patch)
treedf1169012ddf2002ff7da53c47c78c6466b0e0f3 /examples/stm32f7
parentdb889da0446833ff219e652bd68c397af858b999 (diff)
downloadembassy-f0ba79059eea9a2c4f946d86e9e78136bdf99790.zip
Add v1c ethernet driver for the STM32F7 family.
Diffstat (limited to 'examples/stm32f7')
-rw-r--r--examples/stm32f7/Cargo.toml18
-rw-r--r--examples/stm32f7/src/bin/eth.rs128
-rw-r--r--examples/stm32f7/src/example_common.rs12
3 files changed, 156 insertions, 2 deletions
diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml
index cda2d777..f49a23e3 100644
--- a/examples/stm32f7/Cargo.toml
+++ b/examples/stm32f7/Cargo.toml
@@ -19,8 +19,10 @@ defmt-error = []
[dependencies]
embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "defmt-trace"] }
embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] }
-embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "defmt-trace", "stm32f767zi", "unstable-pac", "time-driver-tim2"] }
+embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "defmt-trace", "net", "stm32f767zi", "unstable-pac", "time-driver-tim2"] }
embassy-hal-common = {version = "0.1.0", path = "../../embassy-hal-common" }
+embassy-net = { path = "../../embassy-net", default-features = false, features = ["defmt-debug", "defmt", "tcp", "medium-ethernet", "pool-16"] }
+embassy-macros = { path = "../../embassy-macros" }
defmt = "0.2.3"
defmt-rtt = "0.2.0"
@@ -33,3 +35,17 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
rtt-target = { version = "0.3.1", features = ["cortex-m"] }
heapless = { version = "0.7.5", default-features = false }
nb = "1.0.0"
+rand_core = "0.6.3"
+critical-section = "0.2.3"
+
+
+[dependencies.smoltcp]
+git = "https://github.com/smoltcp-rs/smoltcp"
+rev = "e4241510337e095b9d21136c5f58b2eaa1b78479"
+default-features = false
+features = [
+ "proto-ipv4",
+ "socket",
+ "async",
+ "defmt",
+]
diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs
new file mode 100644
index 00000000..afb86086
--- /dev/null
+++ b/examples/stm32f7/src/bin/eth.rs
@@ -0,0 +1,128 @@
+#![no_std]
+#![no_main]
+#![feature(type_alias_impl_trait)]
+
+#[path = "../example_common.rs"]
+mod example_common;
+use example_common::config;
+
+use cortex_m_rt::entry;
+use defmt::{info, unwrap};
+use defmt_rtt as _; // global logger
+use embassy::executor::{Executor, Spawner};
+use embassy::io::AsyncWriteExt;
+use embassy::time::{Duration, Timer};
+use embassy::util::Forever;
+use embassy_macros::interrupt_take;
+use embassy_net::{
+ Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator, TcpSocket,
+};
+use embassy_stm32::eth::lan8742a::LAN8742A;
+use embassy_stm32::eth::{Ethernet, State};
+use embassy_stm32::rng::Rng;
+use embassy_stm32::{interrupt, peripherals};
+use heapless::Vec;
+use panic_probe as _;
+
+use peripherals::RNG;
+
+#[embassy::task]
+async fn main_task(
+ device: &'static mut Ethernet<'static, LAN8742A, 4, 4>,
+ config: &'static mut StaticConfigurator,
+ spawner: Spawner,
+) {
+ let net_resources = NET_RESOURCES.put(StackResources::new());
+
+ // Init network stack
+ embassy_net::init(device, config, net_resources);
+
+ // Launch network task
+ unwrap!(spawner.spawn(net_task()));
+
+ info!("Network task initialized");
+
+ // Then we can use it!
+ let mut rx_buffer = [0; 1024];
+ let mut tx_buffer = [0; 1024];
+ let mut socket = TcpSocket::new(&mut rx_buffer, &mut tx_buffer);
+
+ socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10)));
+
+ let remote_endpoint = (Ipv4Address::new(192, 168, 0, 10), 8000);
+ let r = socket.connect(remote_endpoint).await;
+ if let Err(e) = r {
+ info!("connect error: {:?}", e);
+ return;
+ }
+ info!("connected!");
+ loop {
+ let r = socket.write_all(b"Hello\n").await;
+ if let Err(e) = r {
+ info!("write error: {:?}", e);
+ return;
+ }
+ Timer::after(Duration::from_secs(1)).await;
+ }
+}
+
+#[embassy::task]
+async fn net_task() {
+ embassy_net::run().await
+}
+
+#[no_mangle]
+fn _embassy_rand(buf: &mut [u8]) {
+ use rand_core::RngCore;
+
+ critical_section::with(|_| unsafe {
+ unwrap!(RNG_INST.as_mut()).fill_bytes(buf);
+ });
+}
+
+static mut RNG_INST: Option<Rng<RNG>> = None;
+
+static EXECUTOR: Forever<Executor> = Forever::new();
+static STATE: Forever<State<'static, 4, 4>> = Forever::new();
+static ETH: Forever<Ethernet<'static, LAN8742A, 4, 4>> = Forever::new();
+static CONFIG: Forever<StaticConfigurator> = Forever::new();
+static NET_RESOURCES: Forever<StackResources<1, 2, 8>> = Forever::new();
+
+#[entry]
+fn main() -> ! {
+ info!("Hello World!");
+
+ info!("Setup RCC...");
+
+ let p = embassy_stm32::init(config());
+
+ let rng = Rng::new(p.RNG);
+ unsafe {
+ RNG_INST.replace(rng);
+ }
+
+ let eth_int = interrupt_take!(ETH);
+ let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
+ let state = STATE.put(State::new());
+
+ let eth = unsafe {
+ ETH.put(Ethernet::new(
+ state, p.ETH, eth_int, p.PA1, p.PA2, p.PC1, p.PA7, p.PC4, p.PC5, p.PG13, p.PB13,
+ p.PG11, LAN8742A, mac_addr, 0,
+ ))
+ };
+
+ let config = StaticConfigurator::new(NetConfig {
+ address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 0, 61), 24),
+ dns_servers: Vec::new(),
+ gateway: Some(Ipv4Address::new(192, 168, 0, 1)),
+ });
+
+ let config = CONFIG.put(config);
+
+ let executor = EXECUTOR.put(Executor::new());
+
+ executor.run(move |spawner| {
+ unwrap!(spawner.spawn(main_task(eth, config, spawner)));
+ })
+}
diff --git a/examples/stm32f7/src/example_common.rs b/examples/stm32f7/src/example_common.rs
index 54d63383..a786cb11 100644
--- a/examples/stm32f7/src/example_common.rs
+++ b/examples/stm32f7/src/example_common.rs
@@ -1,6 +1,9 @@
#![macro_use]
-use defmt_rtt as _; // global logger
+use defmt_rtt as _;
+use embassy_stm32::time::U32Ext;
+use embassy_stm32::Config;
+// global logger
use panic_probe as _;
pub use defmt::*;
@@ -15,3 +18,10 @@ defmt::timestamp! {"{=u64}", {
n as u64
}
}
+
+#[allow(unused)]
+pub fn config() -> Config {
+ let mut config = Config::default();
+ config.rcc.sys_ck = Some(200.mhz().into());
+ config
+}