main.rs (4734B)
1 #![no_std] 2 #![no_main] 3 #![deny( 4 clippy::mem_forget, 5 reason = "mem::forget is generally not safe to do with esp_hal types, especially those \ 6 holding buffers for the duration of a data transfer." 7 )] 8 9 use esp_backtrace as _; 10 use esp_println as _; 11 use esp_alloc as _; 12 13 use alloc::vec::Vec; 14 use alloc::string::String; 15 16 pub mod ecu; 17 pub mod wifi; 18 pub mod mdns; 19 pub mod streamer; 20 pub mod ota; 21 pub mod wibble; 22 23 use getrandom::Error; 24 25 pub fn getrandom_custom(dest: &mut [u8]) -> Result<(), Error> { 26 unsafe { 27 esp_hal::rng::Rng::new().read_into_raw(dest.as_mut_ptr(), dest.len()) 28 }; 29 Ok(()) 30 } 31 use getrandom::register_custom_getrandom; 32 register_custom_getrandom!(getrandom_custom); 33 34 use esp_hal::{ 35 timer::timg::TimerGroup, 36 clock::CpuClock, 37 }; 38 39 use embassy_executor::Spawner; 40 41 use esp_radio::{ 42 Controller, 43 wifi::{ 44 ClientConfig, 45 ModeConfig, 46 } 47 }; 48 49 use log::{info}; 50 51 use crate::ecu::Ecu; 52 use crate::ota::Flasher; 53 54 extern crate alloc; 55 56 // This creates a default app-descriptor required by the esp-idf bootloader. 57 // For more information see: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html#application-description> 58 esp_bootloader_esp_idf::esp_app_desc!(); 59 60 const BUILD_ID: &str = env!("BUILD_ID"); 61 62 // If the device has valid wifi credentials but you need to change them, 63 // build with FORCE_WIFI_CHOOSER. 64 // We should figure out some way to let the end-user do this (add a button?) 65 66 const FORCE_WIFI_CHOOSER : bool = option_env!("FORCE_WIFI_CHOOSER").is_some(); 67 68 69 macro_rules! mk_static { 70 ($t:ty,$val:expr) => {{ 71 static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new(); 72 #[deny(unused_attributes)] 73 let x = STATIC_CELL.uninit().write(($val)); 74 x 75 }}; 76 } 77 78 fn wifi_creds_from_nvs(flasher: &mut Flasher) -> Option<(String, String)> { 79 let ssid = flasher.var("ssid"); 80 let secret = flasher.var("secret"); 81 if let (Some(ssid), Some(secret)) = (ssid, secret) { 82 Some((ssid, secret)) 83 } else { 84 None 85 } 86 } 87 88 // #[main] 89 #[esp_rtos::main] 90 async fn main(s : Spawner) { 91 esp_println::logger::init_logger_from_env(); 92 93 let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); 94 let peripherals = esp_hal::init(config); 95 96 esp_alloc::heap_allocator!(size: 92 * 1024); 97 98 // handwaving: we need the timer to schedule tasks for the rtos, 99 // and we need the rtos so that the ble works (assumption: 100 // it needs to receive packets) 101 let timg0 = TimerGroup::new(peripherals.TIMG0); 102 let sw_interrupt = 103 esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT); 104 esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0); 105 106 107 info!("let's go! {}", BUILD_ID); 108 109 let mut ecu = Ecu::new( 110 peripherals.GPIO21, 111 peripherals.GPIO20, 112 peripherals.UART0 113 ); 114 115 116 let mut flasher = Flasher::new(peripherals.FLASH, peripherals.SHA); 117 118 let esp_radio_ctrl = // esp_radio::init().expect("esp_radio init failed"); 119 &*mk_static!(Controller<'static>, esp_radio::init().unwrap()); 120 121 let (mut wifi_controller, interfaces) = 122 esp_radio::wifi::new(esp_radio_ctrl, peripherals.WIFI, Default::default()).unwrap(); 123 let wifi_interface = interfaces.sta; 124 125 let wifi_creds = wifi_creds_from_nvs(&mut flasher); 126 info!("stored wifi creds {:?}", wifi_creds); 127 128 if !FORCE_WIFI_CHOOSER && let Some((wifi_ssid, wifi_secret)) = wifi_creds { 129 info!("using stored wifi creds"); 130 let station_config = ModeConfig::Client(ClientConfig::default() 131 .with_ssid(wifi_ssid) 132 .with_password(wifi_secret)); 133 134 wifi_controller.set_config(&station_config).expect("can't config wifi"); 135 wifi_controller.start_async().await.expect("wifi failed to start"); 136 137 crate::wifi::start_wifi(&s, 138 wifi_controller, wifi_interface, 139 flasher, 140 &mut ecu).await; 141 } else { 142 info!("no stored wifi creds"); 143 144 let station_config = ModeConfig::Client(ClientConfig::default()); 145 wifi_controller.set_config(&station_config).expect("can't config wifi"); 146 wifi_controller.start_async().await.expect("wifi failed to start"); 147 148 let wifi_networks : Vec<[u8;40]> = 149 crate::wifi::scan_networks(&mut wifi_controller).await.into_iter().map( 150 |ap| { 151 let mut s : [u8; 40] = [0u8; 40]; 152 s[0] = (ap.signal_strength & 0x7f) as u8; 153 s[1..7].copy_from_slice(&ap.bssid); 154 let name = ap.ssid.as_bytes(); 155 s[8..(8+name.len())].copy_from_slice(name); 156 s 157 } 158 ).collect(); 159 wibble::run_ble(&esp_radio_ctrl, peripherals.BT, wifi_networks, flasher).await; 160 } 161 }