Skip to content

Commit a3dc45a

Browse files
MabezDevbjoernQ
authored andcommitted
Unify examples (esp-rs#296)
This PR merges the chip specific examples into one folder, inside the esp-wifi project. To simplify building, alias' have been added to `esp-wifi/.cargo/config.toml` per chip to automatically select the right target and enable the chip feature. Add build script detection for invalid features Fix CI, use build instead of check to detect linker errors enable async feature of hal, this breaks because of interrupt definition for systimer upgrade hal rev upgrade hal rev c6 undo binding modifications fix esp now fix esp coex use released hals, update async examples sync example names sync example names Update examples.md Document alias update build alias
1 parent dbe0e49 commit a3dc45a

19 files changed

+1757
-62
lines changed

esp-wifi/.cargo/config.toml

+29-31
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,33 @@
1+
# Alias' for quickly building for different chips or running examples
2+
# By default we enable
3+
# - `embassy-time-timg0` as the examples assume we are using this time driver
4+
# - `embassy-executor-thread` on Xtensa chips to take advantage of the Xtensa specific executor we have in esp-hal
5+
[alias]
6+
esp32 = "run --features esp32 --target xtensa-esp32-none-elf --features esp32-hal/embassy-time-timg0,esp32-hal/embassy-executor-thread"
7+
esp32s2 = "run --features esp32s2 --target xtensa-esp32s2-none-elf --features esp32s2-hal/embassy-time-timg0,esp32s2-hal/embassy-executor-thread"
8+
esp32s3 = "run --features esp32s3 --target xtensa-esp32s3-none-elf --features esp32s3-hal/embassy-time-timg0,esp32s3-hal/embassy-executor-thread"
9+
esp32c2 = "run --features esp32c2 --target riscv32imc-unknown-none-elf --features esp32c2-hal/embassy-time-timg0"
10+
esp32c3 = "run --features esp32c3 --target riscv32imc-unknown-none-elf --features esp32c3-hal/embassy-time-timg0"
11+
esp32c6 = "run --features esp32c6 --target riscv32imac-unknown-none-elf --features esp32c6-hal/embassy-time-timg0"
12+
13+
besp32 = "build --features esp32 --target xtensa-esp32-none-elf --features esp32-hal/embassy-time-timg0,esp32-hal/embassy-executor-thread"
14+
besp32s2 = "build --features esp32s2 --target xtensa-esp32s2-none-elf --features esp32s2-hal/embassy-time-timg0,esp32s2-hal/embassy-executor-thread"
15+
besp32s3 = "build --features esp32s3 --target xtensa-esp32s3-none-elf --features esp32s3-hal/embassy-time-timg0,esp32s3-hal/embassy-executor-thread"
16+
besp32c2 = "build --features esp32c2 --target riscv32imc-unknown-none-elf --features esp32c2-hal/embassy-time-timg0"
17+
besp32c3 = "build --features esp32c3 --target riscv32imc-unknown-none-elf --features esp32c3-hal/embassy-time-timg0"
18+
besp32c6 = "build --features esp32c6 --target riscv32imac-unknown-none-elf --features esp32c6-hal/embassy-time-timg0"
19+
120
[target.riscv32imc-unknown-none-elf]
221
runner = "espflash flash --monitor"
3-
422
rustflags = [
523
"-C", "link-arg=-Tlinkall.x",
624
"-C", "link-arg=-Trom_functions.x",
725

826
"-C", "force-frame-pointers",
927

28+
# Enable the atomic codegen option for RISCV
29+
"-C", "target-feature=+a",
30+
1031
# tell the core library have atomics even though it's not specified in the target definition
1132
"--cfg", "target_has_atomic_load_store",
1233
"--cfg", 'target_has_atomic_load_store="8"',
@@ -23,72 +44,49 @@ rustflags = [
2344

2445
[target.riscv32imac-unknown-none-elf]
2546
runner = "espflash flash --monitor"
26-
2747
rustflags = [
2848
"-C", "link-arg=-Tlinkall.x",
2949
"-C", "link-arg=-Trom_functions.x",
30-
3150
"-C", "force-frame-pointers",
32-
33-
# tell the core library have atomics even though it's not specified in the target definition
34-
"--cfg", "target_has_atomic_load_store",
35-
"--cfg", 'target_has_atomic_load_store="8"',
36-
"--cfg", 'target_has_atomic_load_store="16"',
37-
"--cfg", 'target_has_atomic_load_store="32"',
38-
"--cfg", 'target_has_atomic_load_store="ptr"',
39-
# enable cas
40-
"--cfg", "target_has_atomic",
41-
"--cfg", 'target_has_atomic="8"',
42-
"--cfg", 'target_has_atomic="16"',
43-
"--cfg", 'target_has_atomic="32"',
44-
"--cfg", 'target_has_atomic="ptr"',
4551
]
4652

4753
[target.xtensa-esp32-none-elf]
4854
runner = "espflash flash --monitor"
49-
5055
rustflags = [
51-
#"-C", "linker=rust-lld",
52-
5356
"-C", "link-arg=-Tlinkall.x",
5457
"-C", "link-arg=-Trom_functions.x",
5558
]
5659

5760
[target.xtensa-esp32s3-none-elf]
5861
runner = "espflash flash --monitor"
59-
6062
rustflags = [
61-
#"-C", "linker=rust-lld",
62-
6363
"-C", "link-arg=-Tlinkall.x",
6464
"-C", "link-arg=-Trom_functions.x",
65-
66-
# for now disable loop optimization
67-
"-C", "target-feature=-loop",
6865
]
6966

7067
[target.xtensa-esp32s2-none-elf]
7168
runner = "espflash flash --monitor"
72-
7369
rustflags = [
74-
#"-C", "linker=rust-lld",
75-
7670
"-C", "link-arg=-Tlinkall.x",
7771
"-C", "link-arg=-Trom_functions.x",
7872

7973
# Enable the atomic codegen option for Xtensa
8074
"-C", "target-feature=+s32c1i",
8175

76+
# tell the core library have atomics even though it's not specified in the target definition
77+
"--cfg", "target_has_atomic_load_store",
78+
"--cfg", 'target_has_atomic_load_store="8"',
79+
"--cfg", 'target_has_atomic_load_store="16"',
80+
"--cfg", 'target_has_atomic_load_store="32"',
81+
"--cfg", 'target_has_atomic_load_store="ptr"',
8282
# Tell the `core` library that we have atomics, even though it's not
8383
# specified in the target definition
84+
"--cfg", 'target_has_atomic',
8485
"--cfg", 'target_has_atomic="8"',
8586
"--cfg", 'target_has_atomic="16"',
8687
"--cfg", 'target_has_atomic="32"',
8788
"--cfg", 'target_has_atomic="ptr"',
8889
]
8990

90-
[build]
91-
target = "riscv32imc-unknown-none-elf"
92-
9391
[unstable]
9492
build-std = [ "core" ]

esp-wifi/Cargo.toml

+30-6
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,33 @@ atomic_enum = { workspace = true }
3636
[build-dependencies]
3737
toml-cfg.workspace = true
3838

39+
[dev-dependencies]
40+
esp-println = { workspace = true, features = ["log"] }
41+
esp-backtrace = { workspace = true }
42+
embedded-svc.workspace = true
43+
embassy-executor = { workspace = true }
44+
embassy-time.workspace = true
45+
embassy-futures.workspace = true
46+
futures-util.workspace = true
47+
embassy-net = { workspace = true }
48+
embassy-sync.workspace = true
49+
bleps.workspace = true
50+
embedded-io.workspace = true
51+
embedded-hal-async = { workspace = true }
52+
log = { workspace = true }
53+
smoltcp.workspace = true
54+
static_cell = { workspace = true }
55+
3956
[features]
4057
default = [ "utils", "log" ]
4158

4259
# chip features
43-
esp32c2 = [ "esp32c2-hal", "esp-wifi-sys/esp32c2" ]
44-
esp32c3 = [ "esp32c3-hal", "esp-wifi-sys/esp32c3" ]
45-
esp32c6 = [ "esp32c6-hal", "esp-wifi-sys/esp32c6" ]
46-
esp32 = [ "esp32-hal", "esp-wifi-sys/esp32" ]
47-
esp32s2 = [ "esp32s2-hal", "esp-wifi-sys/esp32s2" ]
48-
esp32s3 = [ "esp32s3-hal", "esp-wifi-sys/esp32s3" ]
60+
esp32c2 = [ "esp32c2-hal", "esp-wifi-sys/esp32c2", "esp-println/esp32c2", "esp-backtrace/esp32c2", "embassy-executor/arch-riscv32" ]
61+
esp32c3 = [ "esp32c3-hal", "esp-wifi-sys/esp32c3", "esp-println/esp32c3", "esp-backtrace/esp32c3", "embassy-executor/arch-riscv32" ]
62+
esp32c6 = [ "esp32c6-hal", "esp-wifi-sys/esp32c6", "esp-println/esp32c6", "esp-backtrace/esp32c6", "embassy-executor/arch-riscv32" ]
63+
esp32 = [ "esp32-hal", "esp-wifi-sys/esp32", "esp-println/esp32", "esp-backtrace/esp32" ]
64+
esp32s2 = [ "esp32s2-hal", "esp-wifi-sys/esp32s2", "esp-println/esp32s2", "esp-backtrace/esp32s2" ]
65+
esp32s3 = [ "esp32s3-hal", "esp-wifi-sys/esp32s3", "esp-println/esp32s3", "esp-backtrace/esp32s3" ]
4966

5067
# async features
5168
async = [
@@ -58,6 +75,13 @@ async = [
5875
"esp32-hal?/embassy",
5976
"esp32s2-hal?/embassy",
6077
"esp32s3-hal?/embassy",
78+
"esp32c3-hal?/async",
79+
"esp32c2-hal?/async",
80+
"esp32c6-hal?/async",
81+
"esp32-hal?/async",
82+
"esp32s2-hal?/async",
83+
"esp32s3-hal?/async",
84+
"bleps/async"
6185
]
6286

6387
embassy-net = ["dep:embassy-net-driver", "async"]

esp-wifi/build.rs

+25
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,31 @@
77
feature = "esp32s3",
88
))]
99
fn main() -> Result<(), String> {
10+
#[cfg(all(feature = "ble", feature = "esp32s2"))]
11+
{
12+
panic!(
13+
r#"
14+
15+
BLE is not supported on this target.
16+
17+
"#
18+
);
19+
}
20+
#[cfg(all(
21+
feature = "coex",
22+
any(feature = "esp32s2", feature = "esp32c2", feature = "esp32c6")
23+
))]
24+
{
25+
panic!(
26+
r#"
27+
28+
COEX is not yet supported on this target.
29+
30+
See https://github.com/esp-rs/esp-wifi/issues/92.
31+
32+
"#
33+
);
34+
}
1035
match std::env::var("OPT_LEVEL") {
1136
Ok(level) => {
1237
if level != "2" && level != "3" {

esp-wifi/examples/access_point.rs

+163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
#![no_std]
2+
#![no_main]
3+
#![feature(c_variadic)]
4+
#![feature(const_mut_refs)]
5+
6+
#[path = "../../examples-util/util.rs"]
7+
mod examples_util;
8+
use examples_util::hal;
9+
10+
use embedded_io::blocking::*;
11+
use embedded_svc::ipv4::Interface;
12+
use embedded_svc::wifi::{AccessPointConfiguration, Configuration, Wifi};
13+
14+
use esp_backtrace as _;
15+
use esp_println::{print, println};
16+
use esp_wifi::initialize;
17+
use esp_wifi::wifi::utils::create_network_interface;
18+
use esp_wifi::wifi::WifiMode;
19+
use esp_wifi::wifi_interface::WifiStack;
20+
use esp_wifi::{current_millis, EspWifiInitFor};
21+
use hal::clock::ClockControl;
22+
use hal::Rng;
23+
use hal::{peripherals::Peripherals, prelude::*};
24+
25+
use smoltcp::iface::SocketStorage;
26+
27+
#[entry]
28+
fn main() -> ! {
29+
#[cfg(feature = "log")]
30+
esp_println::logger::init_logger(log::LevelFilter::Info);
31+
32+
let peripherals = Peripherals::take();
33+
34+
let system = peripherals.SYSTEM.split();
35+
let clocks = ClockControl::max(system.clock_control).freeze();
36+
37+
#[cfg(target_arch = "xtensa")]
38+
let timer = hal::timer::TimerGroup::new(peripherals.TIMG1, &clocks).timer0;
39+
#[cfg(target_arch = "riscv32")]
40+
let timer = hal::systimer::SystemTimer::new(peripherals.SYSTIMER).alarm0;
41+
let init = initialize(
42+
EspWifiInitFor::Wifi,
43+
timer,
44+
Rng::new(peripherals.RNG),
45+
system.radio_clock_control,
46+
&clocks,
47+
)
48+
.unwrap();
49+
50+
let wifi = peripherals.WIFI;
51+
let mut socket_set_entries: [SocketStorage; 3] = Default::default();
52+
let (iface, device, mut controller, sockets) =
53+
create_network_interface(&init, wifi, WifiMode::Ap, &mut socket_set_entries).unwrap();
54+
let mut wifi_stack = WifiStack::new(iface, device, sockets, current_millis);
55+
56+
let client_config = Configuration::AccessPoint(AccessPointConfiguration {
57+
ssid: "esp-wifi".into(),
58+
..Default::default()
59+
});
60+
let res = controller.set_configuration(&client_config);
61+
println!("wifi_set_configuration returned {:?}", res);
62+
63+
controller.start().unwrap();
64+
println!("is wifi started: {:?}", controller.is_started());
65+
66+
println!("{:?}", controller.get_capabilities());
67+
68+
wifi_stack
69+
.set_iface_configuration(&embedded_svc::ipv4::Configuration::Client(
70+
embedded_svc::ipv4::ClientConfiguration::Fixed(embedded_svc::ipv4::ClientSettings {
71+
ip: embedded_svc::ipv4::Ipv4Addr::from(parse_ip("192.168.2.1")),
72+
subnet: embedded_svc::ipv4::Subnet {
73+
gateway: embedded_svc::ipv4::Ipv4Addr::from(parse_ip("192.168.2.1")),
74+
mask: embedded_svc::ipv4::Mask(24),
75+
},
76+
dns: None,
77+
secondary_dns: None,
78+
}),
79+
))
80+
.unwrap();
81+
82+
println!("Start busy loop on main. Connect to the AP `esp-wifi` and point your browser to http://192.168.2.1:8080/");
83+
println!("Use a static IP in the range 192.168.2.2 .. 192.168.2.255, use gateway 192.168.2.1");
84+
85+
let mut rx_buffer = [0u8; 1536];
86+
let mut tx_buffer = [0u8; 1536];
87+
let mut socket = wifi_stack.get_socket(&mut rx_buffer, &mut tx_buffer);
88+
89+
socket.listen(8080).unwrap();
90+
91+
loop {
92+
socket.work();
93+
94+
if !socket.is_open() {
95+
socket.listen(8080).unwrap();
96+
}
97+
98+
if socket.is_connected() {
99+
println!("Connected");
100+
101+
let mut time_out = false;
102+
let wait_end = current_millis() + 20 * 1000;
103+
let mut buffer = [0u8; 1024];
104+
let mut pos = 0;
105+
loop {
106+
if let Ok(len) = socket.read(&mut buffer[pos..]) {
107+
let to_print =
108+
unsafe { core::str::from_utf8_unchecked(&buffer[..(pos + len)]) };
109+
110+
if to_print.contains("\r\n\r\n") {
111+
print!("{}", to_print);
112+
println!();
113+
break;
114+
}
115+
116+
pos += len;
117+
} else {
118+
break;
119+
}
120+
121+
if current_millis() > wait_end {
122+
println!("Timeout");
123+
time_out = true;
124+
break;
125+
}
126+
}
127+
128+
if !time_out {
129+
socket
130+
.write_all(
131+
b"HTTP/1.0 200 OK\r\n\r\n\
132+
<html>\
133+
<body>\
134+
<h1>Hello Rust! Hello esp-wifi!</h1>\
135+
</body>\
136+
</html>\r\n\
137+
",
138+
)
139+
.unwrap();
140+
141+
socket.flush().unwrap();
142+
}
143+
144+
socket.close();
145+
146+
println!("Done\n");
147+
println!();
148+
}
149+
150+
let wait_end = current_millis() + 5 * 1000;
151+
while current_millis() < wait_end {
152+
socket.work();
153+
}
154+
}
155+
}
156+
157+
fn parse_ip(ip: &str) -> [u8; 4] {
158+
let mut result = [0u8; 4];
159+
for (idx, octet) in ip.split(".").into_iter().enumerate() {
160+
result[idx] = u8::from_str_radix(octet, 10).unwrap();
161+
}
162+
result
163+
}

0 commit comments

Comments
 (0)