eculocate

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

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 }