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