aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorCaleb Garrett <[email protected]>2024-02-04 17:19:15 -0500
committerCaleb Garrett <[email protected]>2024-02-04 17:19:15 -0500
commit059d8a82228c0fa90f7709ce362d7629ca028f13 (patch)
tree2f238a6f97d0da953e98e7f8573fdaff0528f855 /examples
parent66f44b95d70547be8e32daac1ab611eec5fbe28a (diff)
parent1f940bf9e868438090ea126eb2267f5e9325fbd4 (diff)
Merge commit '1f940bf9e868438090ea126eb2267f5e9325fbd4' into hash
Diffstat (limited to 'examples')
-rw-r--r--examples/nrf51/.cargo/config.toml9
-rw-r--r--examples/nrf51/Cargo.toml20
-rw-r--r--examples/nrf51/build.rs35
-rw-r--r--examples/nrf51/memory.x5
-rw-r--r--examples/nrf51/src/bin/blinky.rs20
-rw-r--r--examples/rp/src/bin/debounce.rs80
-rw-r--r--examples/rp/src/bin/i2c_slave.rs6
-rw-r--r--examples/stm32f4/src/bin/ws2812_pwm.rs2
-rw-r--r--examples/stm32g4/src/bin/can.rs56
-rw-r--r--examples/stm32h5/src/bin/can.rs74
-rw-r--r--examples/stm32h7/src/bin/can.rs74
-rw-r--r--examples/stm32h7/src/bin/eth_client.rs1
-rw-r--r--examples/stm32h7/src/bin/eth_client_mii.rs142
13 files changed, 520 insertions, 4 deletions
diff --git a/examples/nrf51/.cargo/config.toml b/examples/nrf51/.cargo/config.toml
new file mode 100644
index 000000000..1671f5db1
--- /dev/null
+++ b/examples/nrf51/.cargo/config.toml
@@ -0,0 +1,9 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace nRF51422_xxAA with your chip as listed in `probe-rs chip list`
3runner = "probe-rs run --chip nRF51422_xxAA"
4
5[build]
6target = "thumbv6m-none-eabi"
7
8[env]
9DEFMT_LOG = "trace"
diff --git a/examples/nrf51/Cargo.toml b/examples/nrf51/Cargo.toml
new file mode 100644
index 000000000..d1e919a33
--- /dev/null
+++ b/examples/nrf51/Cargo.toml
@@ -0,0 +1,20 @@
1[package]
2edition = "2021"
3name = "embassy-nrf51-examples"
4version = "0.1.0"
5license = "MIT OR Apache-2.0"
6
7[dependencies]
8embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-4096", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
9embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
10embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf51", "time-driver-rtc1", "unstable-pac", "time", "rt"] }
11
12defmt = "0.3"
13defmt-rtt = "0.4"
14
15cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
16cortex-m-rt = "0.7"
17panic-probe = { version = "0.3", features = ["print-defmt"] }
18
19[profile.release]
20debug = 2
diff --git a/examples/nrf51/build.rs b/examples/nrf51/build.rs
new file mode 100644
index 000000000..30691aa97
--- /dev/null
+++ b/examples/nrf51/build.rs
@@ -0,0 +1,35 @@
1//! This build script copies the `memory.x` file from the crate root into
2//! a directory where the linker can always find it at build time.
3//! For many projects this is optional, as the linker always searches the
4//! project root directory -- wherever `Cargo.toml` is. However, if you
5//! are using a workspace or have a more complicated build setup, this
6//! build script becomes required. Additionally, by requesting that
7//! Cargo re-run the build script whenever `memory.x` is changed,
8//! updating `memory.x` ensures a rebuild of the application with the
9//! new memory settings.
10
11use std::env;
12use std::fs::File;
13use std::io::Write;
14use std::path::PathBuf;
15
16fn main() {
17 // Put `memory.x` in our output directory and ensure it's
18 // on the linker search path.
19 let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
20 File::create(out.join("memory.x"))
21 .unwrap()
22 .write_all(include_bytes!("memory.x"))
23 .unwrap();
24 println!("cargo:rustc-link-search={}", out.display());
25
26 // By default, Cargo will re-run a build script whenever
27 // any file in the project changes. By specifying `memory.x`
28 // here, we ensure the build script is only re-run when
29 // `memory.x` is changed.
30 println!("cargo:rerun-if-changed=memory.x");
31
32 println!("cargo:rustc-link-arg-bins=--nmagic");
33 println!("cargo:rustc-link-arg-bins=-Tlink.x");
34 println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
35}
diff --git a/examples/nrf51/memory.x b/examples/nrf51/memory.x
new file mode 100644
index 000000000..98b3c792f
--- /dev/null
+++ b/examples/nrf51/memory.x
@@ -0,0 +1,5 @@
1MEMORY
2{
3 FLASH : ORIGIN = 0x00000000, LENGTH = 128K
4 RAM : ORIGIN = 0x20000000, LENGTH = 16K
5}
diff --git a/examples/nrf51/src/bin/blinky.rs b/examples/nrf51/src/bin/blinky.rs
new file mode 100644
index 000000000..7c12ffcbc
--- /dev/null
+++ b/examples/nrf51/src/bin/blinky.rs
@@ -0,0 +1,20 @@
1#![no_std]
2#![no_main]
3
4use embassy_executor::Spawner;
5use embassy_nrf::gpio::{Level, Output, OutputDrive};
6use embassy_time::Timer;
7use {defmt_rtt as _, panic_probe as _};
8
9#[embassy_executor::main]
10async fn main(_spawner: Spawner) {
11 let p = embassy_nrf::init(Default::default());
12 let mut led = Output::new(p.P0_21, Level::Low, OutputDrive::Standard);
13
14 loop {
15 led.set_high();
16 Timer::after_millis(300).await;
17 led.set_low();
18 Timer::after_millis(300).await;
19 }
20}
diff --git a/examples/rp/src/bin/debounce.rs b/examples/rp/src/bin/debounce.rs
new file mode 100644
index 000000000..0077f19fc
--- /dev/null
+++ b/examples/rp/src/bin/debounce.rs
@@ -0,0 +1,80 @@
1//! This example shows the ease of debouncing a button with async rust.
2//! Hook up a button or switch between pin 9 and ground.
3
4#![no_std]
5#![no_main]
6
7use defmt::info;
8use embassy_executor::Spawner;
9use embassy_rp::gpio::{Input, Level, Pull};
10use embassy_time::{with_deadline, Duration, Instant, Timer};
11use {defmt_rtt as _, panic_probe as _};
12
13pub struct Debouncer<'a> {
14 input: Input<'a>,
15 debounce: Duration,
16}
17
18impl<'a> Debouncer<'a> {
19 pub fn new(input: Input<'a>, debounce: Duration) -> Self {
20 Self { input, debounce }
21 }
22
23 pub async fn debounce(&mut self) -> Level {
24 loop {
25 let l1 = self.input.get_level();
26
27 self.input.wait_for_any_edge().await;
28
29 Timer::after(self.debounce).await;
30
31 let l2 = self.input.get_level();
32 if l1 != l2 {
33 break l2;
34 }
35 }
36 }
37}
38
39#[embassy_executor::main]
40async fn main(_spawner: Spawner) {
41 let p = embassy_rp::init(Default::default());
42 let mut btn = Debouncer::new(Input::new(p.PIN_9, Pull::Up), Duration::from_millis(20));
43
44 info!("Debounce Demo");
45
46 loop {
47 // button pressed
48 btn.debounce().await;
49 let start = Instant::now();
50 info!("Button Press");
51
52 match with_deadline(start + Duration::from_secs(1), btn.debounce()).await {
53 // Button Released < 1s
54 Ok(_) => {
55 info!("Button pressed for: {}ms", start.elapsed().as_millis());
56 continue;
57 }
58 // button held for > 1s
59 Err(_) => {
60 info!("Button Held");
61 }
62 }
63
64 match with_deadline(start + Duration::from_secs(5), btn.debounce()).await {
65 // Button released <5s
66 Ok(_) => {
67 info!("Button pressed for: {}ms", start.elapsed().as_millis());
68 continue;
69 }
70 // button held for > >5s
71 Err(_) => {
72 info!("Button Long Held");
73 }
74 }
75
76 // wait for button release before handling another press
77 btn.debounce().await;
78 info!("Button pressed for: {}ms", start.elapsed().as_millis());
79 }
80}
diff --git a/examples/rp/src/bin/i2c_slave.rs b/examples/rp/src/bin/i2c_slave.rs
index 479f9a16a..ac470d2be 100644
--- a/examples/rp/src/bin/i2c_slave.rs
+++ b/examples/rp/src/bin/i2c_slave.rs
@@ -26,7 +26,7 @@ async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! {
26 loop { 26 loop {
27 let mut buf = [0u8; 128]; 27 let mut buf = [0u8; 128];
28 match dev.listen(&mut buf).await { 28 match dev.listen(&mut buf).await {
29 Ok(i2c_slave::Command::GeneralCall(len)) => info!("Device recieved general call write: {}", buf[..len]), 29 Ok(i2c_slave::Command::GeneralCall(len)) => info!("Device received general call write: {}", buf[..len]),
30 Ok(i2c_slave::Command::Read) => loop { 30 Ok(i2c_slave::Command::Read) => loop {
31 match dev.respond_to_read(&[state]).await { 31 match dev.respond_to_read(&[state]).await {
32 Ok(x) => match x { 32 Ok(x) => match x {
@@ -40,9 +40,9 @@ async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! {
40 Err(e) => error!("error while responding {}", e), 40 Err(e) => error!("error while responding {}", e),
41 } 41 }
42 }, 42 },
43 Ok(i2c_slave::Command::Write(len)) => info!("Device recieved write: {}", buf[..len]), 43 Ok(i2c_slave::Command::Write(len)) => info!("Device received write: {}", buf[..len]),
44 Ok(i2c_slave::Command::WriteRead(len)) => { 44 Ok(i2c_slave::Command::WriteRead(len)) => {
45 info!("device recieved write read: {:x}", buf[..len]); 45 info!("device received write read: {:x}", buf[..len]);
46 match buf[0] { 46 match buf[0] {
47 // Set the state 47 // Set the state
48 0xC2 => { 48 0xC2 => {
diff --git a/examples/stm32f4/src/bin/ws2812_pwm.rs b/examples/stm32f4/src/bin/ws2812_pwm.rs
index 239709253..6122cea2d 100644
--- a/examples/stm32f4/src/bin/ws2812_pwm.rs
+++ b/examples/stm32f4/src/bin/ws2812_pwm.rs
@@ -91,7 +91,7 @@ async fn main(_spawner: Spawner) {
91 loop { 91 loop {
92 for &color in color_list { 92 for &color in color_list {
93 // with &mut, we can easily reuse same DMA channel multiple times 93 // with &mut, we can easily reuse same DMA channel multiple times
94 ws2812_pwm.gen_waveform(&mut dp.DMA1_CH2, pwm_channel, color).await; 94 ws2812_pwm.waveform_up(&mut dp.DMA1_CH2, pwm_channel, color).await;
95 // ws2812 need at least 50 us low level input to confirm the input data and change it's state 95 // ws2812 need at least 50 us low level input to confirm the input data and change it's state
96 Timer::after_micros(50).await; 96 Timer::after_micros(50).await;
97 // wait until ticker tick 97 // wait until ticker tick
diff --git a/examples/stm32g4/src/bin/can.rs b/examples/stm32g4/src/bin/can.rs
new file mode 100644
index 000000000..727921fba
--- /dev/null
+++ b/examples/stm32g4/src/bin/can.rs
@@ -0,0 +1,56 @@
1#![no_std]
2#![no_main]
3use defmt::*;
4use embassy_executor::Spawner;
5use embassy_stm32::peripherals::*;
6use embassy_stm32::{bind_interrupts, can, Config};
7use embassy_time::Timer;
8use {defmt_rtt as _, panic_probe as _};
9
10bind_interrupts!(struct Irqs {
11 FDCAN1_IT0 => can::IT0InterruptHandler<FDCAN1>;
12 FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>;
13});
14
15#[embassy_executor::main]
16async fn main(_spawner: Spawner) {
17 let config = Config::default();
18
19 let peripherals = embassy_stm32::init(config);
20
21 let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
22
23 // 250k bps
24 can.set_bitrate(250_000);
25
26 info!("Configured");
27
28 //let mut can = can.into_external_loopback_mode();
29 let mut can = can.into_normal_mode();
30
31 let mut i = 0;
32 loop {
33 let frame = can::TxFrame::new(
34 can::TxFrameHeader {
35 len: 1,
36 frame_format: can::FrameFormat::Standard,
37 id: can::StandardId::new(0x123).unwrap().into(),
38 bit_rate_switching: false,
39 marker: None,
40 },
41 &[i],
42 )
43 .unwrap();
44 info!("Writing frame");
45 _ = can.write(&frame).await;
46
47 match can.read().await {
48 Ok(rx_frame) => info!("Rx: {}", rx_frame.data()[0]),
49 Err(_err) => error!("Error in frame"),
50 }
51
52 Timer::after_millis(250).await;
53
54 i += 1;
55 }
56}
diff --git a/examples/stm32h5/src/bin/can.rs b/examples/stm32h5/src/bin/can.rs
new file mode 100644
index 000000000..2906d1576
--- /dev/null
+++ b/examples/stm32h5/src/bin/can.rs
@@ -0,0 +1,74 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_stm32::peripherals::*;
7use embassy_stm32::{bind_interrupts, can, rcc, Config};
8use embassy_time::Timer;
9use {defmt_rtt as _, panic_probe as _};
10
11bind_interrupts!(struct Irqs {
12 FDCAN1_IT0 => can::IT0InterruptHandler<FDCAN1>;
13 FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>;
14});
15
16#[embassy_executor::main]
17async fn main(_spawner: Spawner) {
18 let mut config = Config::default();
19
20 // configure FDCAN to use PLL1_Q at 64 MHz
21 config.rcc.pll1 = Some(rcc::Pll {
22 source: rcc::PllSource::HSI,
23 prediv: rcc::PllPreDiv::DIV4,
24 mul: rcc::PllMul::MUL8,
25 divp: None,
26 divq: Some(rcc::PllDiv::DIV2),
27 divr: None,
28 });
29 config.rcc.fdcan_clock_source = rcc::FdCanClockSource::PLL1_Q;
30
31 let peripherals = embassy_stm32::init(config);
32
33 let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
34
35 can.can.apply_config(
36 can::config::FdCanConfig::default().set_nominal_bit_timing(can::config::NominalBitTiming {
37 sync_jump_width: 1.try_into().unwrap(),
38 prescaler: 8.try_into().unwrap(),
39 seg1: 13.try_into().unwrap(),
40 seg2: 2.try_into().unwrap(),
41 }),
42 );
43
44 info!("Configured");
45
46 let mut can = can.into_external_loopback_mode();
47 //let mut can = can.into_normal_mode();
48
49 let mut i = 0;
50 loop {
51 let frame = can::TxFrame::new(
52 can::TxFrameHeader {
53 len: 1,
54 frame_format: can::FrameFormat::Standard,
55 id: can::StandardId::new(0x123).unwrap().into(),
56 bit_rate_switching: false,
57 marker: None,
58 },
59 &[i],
60 )
61 .unwrap();
62 info!("Writing frame");
63 _ = can.write(&frame).await;
64
65 match can.read().await {
66 Ok(rx_frame) => info!("Rx: {}", rx_frame.data()[0]),
67 Err(_err) => error!("Error in frame"),
68 }
69
70 Timer::after_millis(250).await;
71
72 i += 1;
73 }
74}
diff --git a/examples/stm32h7/src/bin/can.rs b/examples/stm32h7/src/bin/can.rs
new file mode 100644
index 000000000..2906d1576
--- /dev/null
+++ b/examples/stm32h7/src/bin/can.rs
@@ -0,0 +1,74 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_stm32::peripherals::*;
7use embassy_stm32::{bind_interrupts, can, rcc, Config};
8use embassy_time::Timer;
9use {defmt_rtt as _, panic_probe as _};
10
11bind_interrupts!(struct Irqs {
12 FDCAN1_IT0 => can::IT0InterruptHandler<FDCAN1>;
13 FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>;
14});
15
16#[embassy_executor::main]
17async fn main(_spawner: Spawner) {
18 let mut config = Config::default();
19
20 // configure FDCAN to use PLL1_Q at 64 MHz
21 config.rcc.pll1 = Some(rcc::Pll {
22 source: rcc::PllSource::HSI,
23 prediv: rcc::PllPreDiv::DIV4,
24 mul: rcc::PllMul::MUL8,
25 divp: None,
26 divq: Some(rcc::PllDiv::DIV2),
27 divr: None,
28 });
29 config.rcc.fdcan_clock_source = rcc::FdCanClockSource::PLL1_Q;
30
31 let peripherals = embassy_stm32::init(config);
32
33 let mut can = can::Fdcan::new(peripherals.FDCAN1, peripherals.PA11, peripherals.PA12, Irqs);
34
35 can.can.apply_config(
36 can::config::FdCanConfig::default().set_nominal_bit_timing(can::config::NominalBitTiming {
37 sync_jump_width: 1.try_into().unwrap(),
38 prescaler: 8.try_into().unwrap(),
39 seg1: 13.try_into().unwrap(),
40 seg2: 2.try_into().unwrap(),
41 }),
42 );
43
44 info!("Configured");
45
46 let mut can = can.into_external_loopback_mode();
47 //let mut can = can.into_normal_mode();
48
49 let mut i = 0;
50 loop {
51 let frame = can::TxFrame::new(
52 can::TxFrameHeader {
53 len: 1,
54 frame_format: can::FrameFormat::Standard,
55 id: can::StandardId::new(0x123).unwrap().into(),
56 bit_rate_switching: false,
57 marker: None,
58 },
59 &[i],
60 )
61 .unwrap();
62 info!("Writing frame");
63 _ = can.write(&frame).await;
64
65 match can.read().await {
66 Ok(rx_frame) => info!("Rx: {}", rx_frame.data()[0]),
67 Err(_err) => error!("Error in frame"),
68 }
69
70 Timer::after_millis(250).await;
71
72 i += 1;
73 }
74}
diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs
index dcc6e36e2..aeb169e19 100644
--- a/examples/stm32h7/src/bin/eth_client.rs
+++ b/examples/stm32h7/src/bin/eth_client.rs
@@ -65,6 +65,7 @@ async fn main(spawner: Spawner) -> ! {
65 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; 65 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
66 66
67 static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new(); 67 static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new();
68
68 let device = Ethernet::new( 69 let device = Ethernet::new(
69 PACKETS.init(PacketQueue::<16, 16>::new()), 70 PACKETS.init(PacketQueue::<16, 16>::new()),
70 p.ETH, 71 p.ETH,
diff --git a/examples/stm32h7/src/bin/eth_client_mii.rs b/examples/stm32h7/src/bin/eth_client_mii.rs
new file mode 100644
index 000000000..de6ea522a
--- /dev/null
+++ b/examples/stm32h7/src/bin/eth_client_mii.rs
@@ -0,0 +1,142 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_net::tcp::client::{TcpClient, TcpClientState};
7use embassy_net::{Stack, StackResources};
8use embassy_stm32::eth::generic_smi::GenericSMI;
9use embassy_stm32::eth::{Ethernet, PacketQueue};
10use embassy_stm32::peripherals::ETH;
11use embassy_stm32::rng::Rng;
12use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
13use embassy_time::Timer;
14use embedded_io_async::Write;
15use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect};
16use rand_core::RngCore;
17use static_cell::StaticCell;
18use {defmt_rtt as _, panic_probe as _};
19
20bind_interrupts!(struct Irqs {
21 ETH => eth::InterruptHandler;
22 RNG => rng::InterruptHandler<peripherals::RNG>;
23});
24
25type Device = Ethernet<'static, ETH, GenericSMI>;
26
27#[embassy_executor::task]
28async fn net_task(stack: &'static Stack<Device>) -> ! {
29 stack.run().await
30}
31
32#[embassy_executor::main]
33async fn main(spawner: Spawner) -> ! {
34 let mut config = Config::default();
35 {
36 use embassy_stm32::rcc::*;
37 config.rcc.hsi = Some(HSIPrescaler::DIV1);
38 config.rcc.csi = true;
39 config.rcc.hsi48 = Some(Default::default()); // needed for RNG
40 config.rcc.pll1 = Some(Pll {
41 source: PllSource::HSI,
42 prediv: PllPreDiv::DIV4,
43 mul: PllMul::MUL50,
44 divp: Some(PllDiv::DIV2),
45 divq: None,
46 divr: None,
47 });
48 config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz
49 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz
50 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz
51 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz
52 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz
53 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz
54 config.rcc.voltage_scale = VoltageScale::Scale1;
55 }
56 let p = embassy_stm32::init(config);
57 info!("Hello World!");
58
59 // Generate random seed.
60 let mut rng = Rng::new(p.RNG, Irqs);
61 let mut seed = [0; 8];
62 rng.fill_bytes(&mut seed);
63 let seed = u64::from_le_bytes(seed);
64
65 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
66
67 static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new();
68
69 let device = Ethernet::new_mii(
70 PACKETS.init(PacketQueue::<16, 16>::new()),
71 p.ETH,
72 Irqs,
73 p.PA1,
74 p.PC3,
75 p.PA2,
76 p.PC1,
77 p.PA7,
78 p.PC4,
79 p.PC5,
80 p.PB0,
81 p.PB1,
82 p.PG13,
83 p.PG12,
84 p.PC2,
85 p.PE2,
86 p.PG11,
87 GenericSMI::new(1),
88 mac_addr,
89 );
90 info!("Device created");
91
92 let config = embassy_net::Config::dhcpv4(Default::default());
93 //let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 {
94 // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24),
95 // dns_servers: Vec::new(),
96 // gateway: Some(Ipv4Address::new(10, 42, 0, 1)),
97 //});
98
99 // Init network stack
100 static STACK: StaticCell<Stack<Device>> = StaticCell::new();
101 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
102 let stack = &*STACK.init(Stack::new(
103 device,
104 config,
105 RESOURCES.init(StackResources::<3>::new()),
106 seed,
107 ));
108
109 // Launch network task
110 unwrap!(spawner.spawn(net_task(stack)));
111
112 // Ensure DHCP configuration is up before trying connect
113 stack.wait_config_up().await;
114
115 info!("Network task initialized");
116
117 let state: TcpClientState<1, 1024, 1024> = TcpClientState::new();
118 let client = TcpClient::new(&stack, &state);
119
120 loop {
121 // You need to start a server on the host machine, for example: `nc -l 8000`
122 let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(192, 168, 100, 1), 8000));
123
124 info!("connecting...");
125 let r = client.connect(addr).await;
126 if let Err(e) = r {
127 info!("connect error: {:?}", e);
128 Timer::after_secs(1).await;
129 continue;
130 }
131 let mut connection = r.unwrap();
132 info!("connected!");
133 loop {
134 let r = connection.write_all(b"Hello\n").await;
135 if let Err(e) = r {
136 info!("write error: {:?}", e);
137 break;
138 }
139 Timer::after_secs(1).await;
140 }
141 }
142}