diff options
author | Matous Hybl <hyblmatous@gmail.com> | 2021-10-28 14:22:02 +0200 |
---|---|---|
committer | Matous Hybl <hyblmatous@gmail.com> | 2021-11-10 10:16:46 +0100 |
commit | f0ba79059eea9a2c4f946d86e9e78136bdf99790 (patch) | |
tree | df1169012ddf2002ff7da53c47c78c6466b0e0f3 /examples/stm32f7 | |
parent | db889da0446833ff219e652bd68c397af858b999 (diff) | |
download | embassy-f0ba79059eea9a2c4f946d86e9e78136bdf99790.zip |
Add v1c ethernet driver for the STM32F7 family.
Diffstat (limited to 'examples/stm32f7')
-rw-r--r-- | examples/stm32f7/Cargo.toml | 18 | ||||
-rw-r--r-- | examples/stm32f7/src/bin/eth.rs | 128 | ||||
-rw-r--r-- | examples/stm32f7/src/example_common.rs | 12 |
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 +} |