http_hello.rs
1 #![no_std] 2 #![no_main] 3 #![feature(impl_trait_in_assoc_type)] 4 5 extern crate alloc; 6 7 use defmt::info; 8 use embassy_executor::Spawner; 9 use embassy_net::{Runner, StackResources}; 10 use embassy_time::{Duration, Timer, with_timeout}; 11 use esp_hal::{ 12 clock::CpuClock, 13 interrupt::software::SoftwareInterruptControl, 14 rng::Rng, 15 timer::timg::TimerGroup, 16 }; 17 use esp_radio::wifi::{Config, ControllerConfig, Interface, WifiController, sta::StationConfig}; 18 use panic_rtt_target as _; 19 use picoserve::AppBuilder; 20 use static_cell::StaticCell; 21 22 use firmware::{config::app, services::http::HttpAppProps}; 23 24 const WIFI_SSID: &str = env!("WIFI_SSID"); 25 const WIFI_PASSWORD: &str = env!("WIFI_PSK"); 26 27 macro_rules! mk_static { 28 ($type:ty, $value:expr) => {{ 29 static STATIC_CELL: StaticCell<$type> = StaticCell::new(); 30 STATIC_CELL.uninit().write($value) 31 }}; 32 } 33 34 esp_bootloader_esp_idf::esp_app_desc!(); 35 36 fn random_seed(rng: &mut Rng) -> u64 { 37 (u64::from(rng.random()) << 32) | u64::from(rng.random()) 38 } 39 40 #[embassy_executor::task] 41 async fn wifi_connection_task(mut ctrl: WifiController<'static>) { 42 loop { 43 info!("attempting Wi-Fi connection"); 44 match ctrl.connect_async().await { 45 Ok(_connected_info) => { 46 info!("Wi-Fi connected"); 47 let _ = ctrl.wait_for_disconnect_async().await; 48 } 49 Err(e) => { 50 info!("Wi-Fi connect failed: {:?}", e); 51 Timer::after(Duration::from_secs(2)).await; 52 } 53 } 54 } 55 } 56 57 #[embassy_executor::task] 58 async fn network_task(mut runner: Runner<'static, Interface<'static>>) { 59 runner.run().await; 60 } 61 62 #[esp_rtos::main] 63 async fn main(spawner: Spawner) -> ! { 64 rtt_target::rtt_init_defmt!(); 65 66 let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); 67 let peripherals = esp_hal::init(config); 68 69 esp_alloc::heap_allocator!(#[esp_hal::ram(reclaimed)] size: 64 * 1024); 70 esp_alloc::heap_allocator!(size: 64 * 1024); 71 72 let timg0 = TimerGroup::new(peripherals.TIMG0); 73 let sw_ints = SoftwareInterruptControl::new(peripherals.SW_INTERRUPT); 74 esp_rtos::start(timg0.timer0, sw_ints.software_interrupt0); 75 76 let station_config = Config::Station( 77 StationConfig::default() 78 .with_ssid(WIFI_SSID) 79 .with_password(WIFI_PASSWORD.into()), 80 ); 81 82 let (wifi_ctrl, interfaces) = esp_radio::wifi::new( 83 peripherals.WIFI, 84 ControllerConfig::default().with_initial_config(station_config), 85 ) 86 .unwrap(); 87 88 let mut rng = Rng::new(); 89 let (stack, runner) = embassy_net::new( 90 interfaces.station, 91 embassy_net::Config::dhcpv4(Default::default()), 92 mk_static!(StackResources<3>, StackResources::<3>::new()), 93 random_seed(&mut rng), 94 ); 95 96 spawner.spawn(wifi_connection_task(wifi_ctrl).unwrap()); 97 spawner.spawn(network_task(runner).unwrap()); 98 99 with_timeout(Duration::from_secs(30), stack.wait_config_up()) 100 .await 101 .unwrap(); 102 103 info!("DHCP: {}", stack.config_v4().unwrap().address); 104 105 let app = mk_static!( 106 picoserve::AppRouter<HttpAppProps>, 107 HttpAppProps { stack }.build_app() 108 ); 109 110 spawner.spawn(firmware::services::http::task(0, stack, app).unwrap()); 111 112 info!("HTTP server on port {}", app::http::PORT); 113 114 loop { 115 Timer::after(Duration::from_secs(60)).await; 116 } 117 }