forked from esp-rs/esp-hal
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add basic AP support * Remove IS_AP global static
- Loading branch information
Showing
10 changed files
with
672 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
#![no_std] | ||
#![no_main] | ||
#![feature(c_variadic)] | ||
#![feature(const_mut_refs)] | ||
|
||
#[cfg(feature = "esp32")] | ||
use esp32_hal as hal; | ||
#[cfg(feature = "esp32c2")] | ||
use esp32c2_hal as hal; | ||
#[cfg(feature = "esp32c3")] | ||
use esp32c3_hal as hal; | ||
#[cfg(feature = "esp32s2")] | ||
use esp32s2_hal as hal; | ||
#[cfg(feature = "esp32s3")] | ||
use esp32s3_hal as hal; | ||
|
||
use embedded_io::blocking::*; | ||
use embedded_svc::ipv4::Interface; | ||
use embedded_svc::wifi::{AccessPointConfiguration, Configuration, Wifi}; | ||
|
||
use esp_backtrace as _; | ||
use esp_println::logger::init_logger; | ||
use esp_println::{print, println}; | ||
use esp_wifi::current_millis; | ||
use esp_wifi::initialize; | ||
use esp_wifi::wifi::utils::create_network_interface; | ||
use esp_wifi::wifi::WifiMode; | ||
use esp_wifi::wifi_interface::WifiStack; | ||
use hal::clock::{ClockControl, CpuClock}; | ||
use hal::Rng; | ||
use hal::{peripherals::Peripherals, prelude::*, Rtc}; | ||
|
||
#[cfg(any(feature = "esp32c3", feature = "esp32c2"))] | ||
use hal::system::SystemExt; | ||
|
||
#[cfg(any(feature = "esp32c3", feature = "esp32c2"))] | ||
use riscv_rt::entry; | ||
use smoltcp::iface::SocketStorage; | ||
#[cfg(any(feature = "esp32", feature = "esp32s3", feature = "esp32s2"))] | ||
use xtensa_lx_rt::entry; | ||
|
||
#[entry] | ||
fn main() -> ! { | ||
init_logger(log::LevelFilter::Info); | ||
esp_wifi::init_heap(); | ||
|
||
let peripherals = Peripherals::take(); | ||
|
||
#[cfg(not(feature = "esp32"))] | ||
let system = peripherals.SYSTEM.split(); | ||
#[cfg(feature = "esp32")] | ||
let system = peripherals.DPORT.split(); | ||
|
||
#[cfg(feature = "esp32c3")] | ||
let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock160MHz).freeze(); | ||
#[cfg(feature = "esp32c2")] | ||
let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock120MHz).freeze(); | ||
#[cfg(any(feature = "esp32", feature = "esp32s3", feature = "esp32s2"))] | ||
let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock240MHz).freeze(); | ||
|
||
let mut rtc = Rtc::new(peripherals.RTC_CNTL); | ||
|
||
// Disable watchdog timers | ||
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))] | ||
rtc.swd.disable(); | ||
|
||
rtc.rwdt.disable(); | ||
|
||
let mut socket_set_entries: [SocketStorage; 3] = Default::default(); | ||
let (iface, device, mut controller, sockets) = | ||
create_network_interface(WifiMode::Ap, &mut socket_set_entries); | ||
let mut wifi_stack = WifiStack::new(iface, device, sockets, current_millis); | ||
|
||
#[cfg(any(feature = "esp32c3", feature = "esp32c2"))] | ||
{ | ||
use hal::systimer::SystemTimer; | ||
let syst = SystemTimer::new(peripherals.SYSTIMER); | ||
initialize(syst.alarm0, Rng::new(peripherals.RNG), &clocks).unwrap(); | ||
} | ||
#[cfg(any(feature = "esp32", feature = "esp32s3", feature = "esp32s2"))] | ||
{ | ||
use hal::timer::TimerGroup; | ||
let timg1 = TimerGroup::new(peripherals.TIMG1, &clocks); | ||
initialize(timg1.timer0, Rng::new(peripherals.RNG), &clocks).unwrap(); | ||
} | ||
|
||
let client_config = Configuration::AccessPoint(AccessPointConfiguration { | ||
ssid: "esp-wifi".into(), | ||
..Default::default() | ||
}); | ||
let res = controller.set_configuration(&client_config); | ||
println!("wifi_set_configuration returned {:?}", res); | ||
|
||
controller.start().unwrap(); | ||
println!("is wifi started: {:?}", controller.is_started()); | ||
|
||
println!("{:?}", controller.get_capabilities()); | ||
|
||
wifi_stack | ||
.set_iface_configuration(&embedded_svc::ipv4::Configuration::Client( | ||
embedded_svc::ipv4::ClientConfiguration::Fixed(embedded_svc::ipv4::ClientSettings { | ||
ip: embedded_svc::ipv4::Ipv4Addr::from(parse_ip("192.168.2.1")), | ||
subnet: embedded_svc::ipv4::Subnet { | ||
gateway: embedded_svc::ipv4::Ipv4Addr::from(parse_ip("192.168.2.1")), | ||
mask: embedded_svc::ipv4::Mask(24), | ||
}, | ||
dns: None, | ||
secondary_dns: None, | ||
}), | ||
)) | ||
.unwrap(); | ||
|
||
println!("Start busy loop on main. Connect to the AP `esp-wifi` and point your browser to http://192.168.2.1:8080/"); | ||
println!("Use a static IP in the range 192.168.2.2 .. 192.168.2.255, use gateway 192.168.2.1"); | ||
|
||
let mut rx_buffer = [0u8; 1536]; | ||
let mut tx_buffer = [0u8; 1536]; | ||
let mut socket = wifi_stack.get_socket(&mut rx_buffer, &mut tx_buffer); | ||
|
||
socket.listen(8080).unwrap(); | ||
|
||
loop { | ||
socket.work(); | ||
|
||
if !socket.is_open() { | ||
socket.listen(8080).unwrap(); | ||
} | ||
|
||
if socket.is_connected() { | ||
println!("Connected"); | ||
|
||
let mut time_out = false; | ||
let wait_end = current_millis() + 20 * 1000; | ||
let mut buffer = [0u8; 1024]; | ||
let mut pos = 0; | ||
loop { | ||
if let Ok(len) = socket.read(&mut buffer[pos..]) { | ||
let to_print = | ||
unsafe { core::str::from_utf8_unchecked(&buffer[..(pos + len)]) }; | ||
|
||
if to_print.contains("\r\n\r\n") { | ||
print!("{}", to_print); | ||
println!(); | ||
break; | ||
} | ||
|
||
pos += len; | ||
} else { | ||
break; | ||
} | ||
|
||
if current_millis() > wait_end { | ||
println!("Timeout"); | ||
time_out = true; | ||
break; | ||
} | ||
} | ||
|
||
if !time_out { | ||
socket | ||
.write_all( | ||
b"HTTP/1.0 200 OK\r\n\r\n\ | ||
<html>\ | ||
<body>\ | ||
<h1>Hello Rust! Hello esp-wifi!</h1>\ | ||
</body>\ | ||
</html>\r\n\ | ||
", | ||
) | ||
.unwrap(); | ||
|
||
socket.flush().unwrap(); | ||
} | ||
|
||
socket.close(); | ||
|
||
println!("Done\n"); | ||
println!(); | ||
} | ||
|
||
let wait_end = current_millis() + 5 * 1000; | ||
while current_millis() < wait_end { | ||
socket.work(); | ||
} | ||
} | ||
} | ||
|
||
fn parse_ip(ip: &str) -> [u8; 4] { | ||
let mut result = [0u8; 4]; | ||
for (idx, octet) in ip.split(".").into_iter().enumerate() { | ||
result[idx] = u8::from_str_radix(octet, 10).unwrap(); | ||
} | ||
result | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.