1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
use defmt::*;
use embassy_executor::Spawner;
use embassy_net::tcp::client::{TcpClient, TcpClientState};
use embassy_net::{Stack, StackResources};
use embassy_stm32::eth::generic_smi::GenericSMI;
use embassy_stm32::eth::{Ethernet, PacketQueue};
use embassy_stm32::peripherals::ETH;
use embassy_stm32::rng::Rng;
use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
use embassy_time::Timer;
use embedded_io_async::Write;
use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect};
use rand_core::RngCore;
use static_cell::make_static;
use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs {
ETH => eth::InterruptHandler;
RNG => rng::InterruptHandler<peripherals::RNG>;
});
type Device = Ethernet<'static, ETH, GenericSMI>;
#[embassy_executor::task]
async fn net_task(stack: &'static Stack<Device>) -> ! {
stack.run().await
}
#[embassy_executor::main]
async fn main(spawner: Spawner) -> ! {
let mut config = Config::default();
{
use embassy_stm32::rcc::*;
config.rcc.hsi = Some(HSIPrescaler::DIV1);
config.rcc.csi = true;
config.rcc.hsi48 = true; // needed for RNG
config.rcc.pll1 = Some(Pll {
source: PllSource::HSI,
prediv: PllPreDiv::DIV4,
mul: PllMul::MUL50,
divp: Some(PllDiv::DIV2),
divq: None,
divr: None,
});
config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz
config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz
config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz
config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz
config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz
config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz
config.rcc.voltage_scale = VoltageScale::Scale1;
}
let p = embassy_stm32::init(config);
info!("Hello World!");
// Generate random seed.
let mut rng = Rng::new(p.RNG, Irqs);
let mut seed = [0; 8];
rng.fill_bytes(&mut seed);
let seed = u64::from_le_bytes(seed);
let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
let device = Ethernet::new(
make_static!(PacketQueue::<16, 16>::new()),
p.ETH,
Irqs,
p.PA1,
p.PA2,
p.PC1,
p.PA7,
p.PC4,
p.PC5,
p.PG13,
p.PB13,
p.PG11,
GenericSMI::new(0),
mac_addr,
);
let config = embassy_net::Config::dhcpv4(Default::default());
//let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 {
// address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24),
// dns_servers: Vec::new(),
// gateway: Some(Ipv4Address::new(10, 42, 0, 1)),
//});
// Init network stack
let stack = &*make_static!(Stack::new(
device,
config,
make_static!(StackResources::<2>::new()),
seed
));
// Launch network task
unwrap!(spawner.spawn(net_task(stack)));
// Ensure DHCP configuration is up before trying connect
stack.wait_config_up().await;
info!("Network task initialized");
let state: TcpClientState<1, 1024, 1024> = TcpClientState::new();
let client = TcpClient::new(&stack, &state);
loop {
let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(10, 42, 0, 1), 8000));
info!("connecting...");
let r = client.connect(addr).await;
if let Err(e) = r {
info!("connect error: {:?}", e);
Timer::after_secs(1).await;
continue;
}
let mut connection = r.unwrap();
info!("connected!");
loop {
let r = connection.write_all(b"Hello\n").await;
if let Err(e) = r {
info!("write error: {:?}", e);
break;
}
Timer::after_secs(1).await;
}
}
}
|