Files
eculocate/ecu-esp32/src/main.rs
T

162 lines
4.6 KiB
Rust

#![no_std]
#![no_main]
#![deny(
clippy::mem_forget,
reason = "mem::forget is generally not safe to do with esp_hal types, especially those \
holding buffers for the duration of a data transfer."
)]
use esp_backtrace as _;
use esp_println as _;
use esp_alloc as _;
use alloc::vec::Vec;
use alloc::string::String;
pub mod ecu;
pub mod wifi;
pub mod mdns;
pub mod streamer;
pub mod ota;
pub mod wibble;
use getrandom::Error;
pub fn getrandom_custom(dest: &mut [u8]) -> Result<(), Error> {
unsafe {
esp_hal::rng::Rng::new().read_into_raw(dest.as_mut_ptr(), dest.len())
};
Ok(())
}
use getrandom::register_custom_getrandom;
register_custom_getrandom!(getrandom_custom);
use esp_hal::{
timer::timg::TimerGroup,
clock::CpuClock,
};
use embassy_executor::Spawner;
use esp_radio::{
Controller,
wifi::{
ClientConfig,
ModeConfig,
}
};
use log::{info};
use crate::ecu::Ecu;
use crate::ota::Flasher;
extern crate alloc;
// This creates a default app-descriptor required by the esp-idf bootloader.
// For more information see: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html#application-description>
esp_bootloader_esp_idf::esp_app_desc!();
const BUILD_ID: &str = env!("BUILD_ID");
// If the device has valid wifi credentials but you need to change them,
// build with FORCE_WIFI_CHOOSER.
// We should figure out some way to let the end-user do this (add a button?)
const FORCE_WIFI_CHOOSER : bool = option_env!("FORCE_WIFI_CHOOSER").is_some();
macro_rules! mk_static {
($t:ty,$val:expr) => {{
static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new();
#[deny(unused_attributes)]
let x = STATIC_CELL.uninit().write(($val));
x
}};
}
fn wifi_creds_from_nvs(flasher: &mut Flasher) -> Option<(String, String)> {
let ssid = flasher.var("ssid");
let secret = flasher.var("secret");
if let (Some(ssid), Some(secret)) = (ssid, secret) {
Some((ssid, secret))
} else {
None
}
}
// #[main]
#[esp_rtos::main]
async fn main(s : Spawner) {
esp_println::logger::init_logger_from_env();
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config);
esp_alloc::heap_allocator!(size: 92 * 1024);
// handwaving: we need the timer to schedule tasks for the rtos,
// and we need the rtos so that the ble works (assumption:
// it needs to receive packets)
let timg0 = TimerGroup::new(peripherals.TIMG0);
let sw_interrupt =
esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0);
info!("let's go! {}", BUILD_ID);
let mut ecu = Ecu::new(
peripherals.GPIO21,
peripherals.GPIO20,
peripherals.UART0
);
let mut flasher = Flasher::new(peripherals.FLASH, peripherals.SHA);
let esp_radio_ctrl = // esp_radio::init().expect("esp_radio init failed");
&*mk_static!(Controller<'static>, esp_radio::init().unwrap());
let (mut wifi_controller, interfaces) =
esp_radio::wifi::new(esp_radio_ctrl, peripherals.WIFI, Default::default()).unwrap();
let wifi_interface = interfaces.sta;
let wifi_creds = wifi_creds_from_nvs(&mut flasher);
info!("stored wifi creds {:?}", wifi_creds);
if !FORCE_WIFI_CHOOSER && let Some((wifi_ssid, wifi_secret)) = wifi_creds {
info!("using stored wifi creds");
let station_config = ModeConfig::Client(ClientConfig::default()
.with_ssid(wifi_ssid)
.with_password(wifi_secret));
wifi_controller.set_config(&station_config).expect("can't config wifi");
wifi_controller.start_async().await.expect("wifi failed to start");
crate::wifi::start_wifi(&s,
wifi_controller, wifi_interface,
flasher,
&mut ecu).await;
} else {
info!("no stored wifi creds");
let station_config = ModeConfig::Client(ClientConfig::default());
wifi_controller.set_config(&station_config).expect("can't config wifi");
wifi_controller.start_async().await.expect("wifi failed to start");
let wifi_networks : Vec<[u8;40]> =
crate::wifi::scan_networks(&mut wifi_controller).await.into_iter().map(
|ap| {
let mut s : [u8; 40] = [0u8; 40];
s[0] = (ap.signal_strength & 0x7f) as u8;
s[1..7].copy_from_slice(&ap.bssid);
let name = ap.ssid.as_bytes();
s[8..(8+name.len())].copy_from_slice(name);
s
}
).collect();
wibble::run_ble(&esp_radio_ctrl, peripherals.BT, wifi_networks, flasher).await;
}
}