microvisor.rs
1 #![no_std] 2 #![no_main] 3 #![feature(impl_trait_in_assoc_type)] 4 #![deny( 5 clippy::mem_forget, 6 reason = "mem::forget is generally not safe to do with esp_hal types, especially those \ 7 holding buffers for the duration of a data transfer." 8 )] 9 #![deny(clippy::large_stack_frames)] 10 11 extern crate alloc; 12 13 use defmt::info; 14 use embassy_executor::Spawner; 15 use embassy_time::{Duration, Timer}; 16 use esp_hal::{ 17 clock::CpuClock, 18 delay::Delay, 19 gpio::{Level, Output, OutputConfig}, 20 interrupt::software::SoftwareInterruptControl, 21 timer::timg::TimerGroup, 22 }; 23 use esp_storage::FlashStorage; 24 use panic_rtt_target as _; 25 26 use firmware::{ 27 boot, 28 config::{app, board}, 29 networking::wifi, 30 }; 31 32 esp_bootloader_esp_idf::esp_app_desc!(); 33 34 #[allow( 35 clippy::large_stack_frames, 36 reason = "it's not unusual to allocate larger buffers etc. in main" 37 )] 38 #[esp_rtos::main] 39 async fn main(spawner: Spawner) -> ! { 40 rtt_target::rtt_init_defmt!(); 41 42 let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); 43 let peripherals = esp_hal::init(config); 44 45 esp_alloc::heap_allocator!(#[esp_hal::ram(reclaimed)] size: 73744); 46 // 32 KB — shares SRAM with main thread stack. Was 64 KB but 47 // smoltcp::Interface::new() overflows the stack during embassy_net init. 48 // PSRAM handles bulk allocations; keep this small. 49 esp_alloc::heap_allocator!(size: 32 * 1024); 50 esp_alloc::psram_allocator!(peripherals.PSRAM, esp_hal::psram); 51 52 let timg0 = TimerGroup::new(peripherals.TIMG0); 53 let sw_ints = SoftwareInterruptControl::new(peripherals.SW_INTERRUPT); 54 esp_rtos::start(timg0.timer0, sw_ints.software_interrupt0); 55 56 info!("Embassy initialized!"); 57 info!("host_platform={}", board::PLATFORM); 58 info!("active_user_key={}", app::ACTIVE_USER_KEY); 59 info!("time_zone={}", app::time::ZONE); 60 info!( 61 "filesystem.sd_card: device={} fs_type={} data_log_path={}", 62 app::sd_card::DEVICE, 63 app::sd_card::FS_TYPE, 64 app::sd_card::DATA_LOG_PATH 65 ); 66 info!( 67 "networking.ap_fallback={} ap_ssid={} ap_channel={} ap_max_connections={} ap_auth_mode={}", 68 app::wifi::FALLBACK_TO_AP, 69 app::wifi::ap::SSID, 70 app::wifi::ap::CHANNEL, 71 app::wifi::ap::MAX_CONNECTIONS, 72 app::wifi::ap::AUTH_MODE, 73 ); 74 75 let mut flash = FlashStorage::new(peripherals.FLASH).multicore_auto_park(); 76 boot::validate_ota_slot(&mut flash); 77 78 let _sensor_power_relay = match board::i2c::LEGACY_POWER_GPIO { 79 5 => Output::new(peripherals.GPIO5, Level::High, OutputConfig::default()), 80 unsupported_gpio => { 81 panic!("unsupported sensor_power_enable_gpio={}", unsupported_gpio) 82 } 83 }; 84 Delay::new().delay_millis(1_000); 85 86 boot::initialize_sd_and_filesystem( 87 peripherals.SPI2, 88 peripherals.GPIO10, 89 peripherals.GPIO11, 90 peripherals.GPIO12, 91 peripherals.GPIO13, 92 ); 93 94 let (mut i2c0_bus, mut i2c1_bus) = boot::initialize_i2c_buses( 95 peripherals.I2C0, 96 peripherals.I2C1, 97 peripherals.GPIO8, 98 peripherals.GPIO9, 99 peripherals.GPIO17, 100 peripherals.GPIO18, 101 ); 102 boot::discover_i2c_devices(&mut i2c0_bus, &mut i2c1_bus).await; 103 104 let credentials = wifi::load_credentials_or_default(&mut flash); 105 106 let network = boot::initialize_networking( 107 spawner, 108 peripherals.WIFI, 109 peripherals.BT, 110 &credentials, 111 ) 112 .await; 113 114 boot::spawn_sensor_tasks(&spawner, &mut i2c0_bus, &mut i2c1_bus); 115 boot::start_services(&spawner, network.stack, flash); 116 117 let _ble_controller = network.ble_controller; 118 loop { 119 Timer::after(Duration::from_secs(60)).await; 120 } 121 }