enable deepsleep and gpio1 + timer wake
This commit is contained in:
@@ -21,14 +21,14 @@ use embassy_executor::Spawner;
|
||||
use embassy_net::udp::UdpSocket;
|
||||
use embassy_net::{DhcpConfig, Ipv4Cidr, Runner, Stack, StackResources, StaticConfigV4};
|
||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_sync::mutex::Mutex;
|
||||
use embassy_sync::mutex::{Mutex, MutexGuard};
|
||||
use embassy_time::{Duration, Timer};
|
||||
use embedded_storage::nor_flash::ReadNorFlash;
|
||||
use esp_bootloader_esp_idf::ota::{Ota, OtaImageState};
|
||||
use esp_bootloader_esp_idf::partitions::FlashRegion;
|
||||
use esp_hal::gpio::Input;
|
||||
use esp_hal::gpio::{Input, InputConfig, Pull, RtcPinWithResistors};
|
||||
use esp_hal::rng::Rng;
|
||||
use esp_hal::rtc_cntl::sleep::RtcSleepConfig;
|
||||
use esp_hal::rtc_cntl::{sleep::{TimerWakeupSource, WakeupLevel}, Rtc};
|
||||
use esp_hal::system::software_reset;
|
||||
use esp_println::println;
|
||||
use esp_storage::FlashStorage;
|
||||
@@ -113,6 +113,9 @@ pub struct Esp<'a> {
|
||||
|
||||
pub boot_button: Input<'a>,
|
||||
|
||||
// RTC-capable GPIO used as external wake source (store the raw peripheral)
|
||||
pub wake_gpio1: esp_hal::peripherals::GPIO1<'static>,
|
||||
|
||||
pub ota: Ota<'static, FlashStorage>,
|
||||
pub ota_next: &'static mut FlashRegion<'static, FlashStorage>,
|
||||
}
|
||||
@@ -409,14 +412,12 @@ impl Esp<'_> {
|
||||
spawner.spawn(run_dhcp(stack.clone(), gw_ip_addr_str)).ok();
|
||||
|
||||
loop {
|
||||
println!("waiting for wifi ap link up");
|
||||
if stack.is_link_up() {
|
||||
break;
|
||||
}
|
||||
Timer::after(Duration::from_millis(500)).await;
|
||||
}
|
||||
while !stack.is_config_up() {
|
||||
println!("waiting for wifi ap config up");
|
||||
Timer::after(Duration::from_millis(100)).await
|
||||
}
|
||||
println!("Connect to the AP `${ssid}` and point your browser to http://{gw_ip_addr_str}/");
|
||||
@@ -481,92 +482,79 @@ impl Esp<'_> {
|
||||
spawner.spawn(net_task(runner)).ok();
|
||||
self.controller.lock().await.start_async().await?;
|
||||
|
||||
let timeout = TIME_ACCESS.get().await.current_time_us() + max_wait as u64 * 1000;
|
||||
let timeout = {
|
||||
let guard = TIME_ACCESS.get().await.lock().await;
|
||||
guard.current_time_us()
|
||||
} + max_wait as u64 * 1000;
|
||||
loop {
|
||||
let state = esp_wifi::wifi::sta_state();
|
||||
println!("waiting wifi sta ready {:?}", state);
|
||||
match state {
|
||||
WifiState::StaStarted => {
|
||||
self.controller.lock().await.connect()?;
|
||||
break;
|
||||
}
|
||||
WifiState::StaConnected => {}
|
||||
WifiState::StaDisconnected => {}
|
||||
WifiState::StaStopped => {}
|
||||
WifiState::ApStarted => {}
|
||||
WifiState::ApStopped => {}
|
||||
WifiState::Invalid => {}
|
||||
_ => {}
|
||||
}
|
||||
if TIME_ACCESS.get().await.current_time_us() > timeout {
|
||||
if { let guard = TIME_ACCESS.get().await.lock().await; guard.current_time_us() } > timeout {
|
||||
bail!("Timeout waiting for wifi sta ready")
|
||||
}
|
||||
Timer::after(Duration::from_millis(500)).await;
|
||||
}
|
||||
let timeout = TIME_ACCESS.get().await.current_time_us() + max_wait as u64 * 1000;
|
||||
let timeout = { let guard = TIME_ACCESS.get().await.lock().await; guard.current_time_us() } + max_wait as u64 * 1000;
|
||||
loop {
|
||||
let state = esp_wifi::wifi::sta_state();
|
||||
println!("waiting wifi sta connected {:?}", state);
|
||||
match state {
|
||||
WifiState::StaStarted => {}
|
||||
WifiState::StaConnected => {
|
||||
break;
|
||||
}
|
||||
WifiState::StaDisconnected => {}
|
||||
WifiState::StaStopped => {}
|
||||
WifiState::ApStarted => {}
|
||||
WifiState::ApStopped => {}
|
||||
WifiState::Invalid => {}
|
||||
_ => {}
|
||||
}
|
||||
if TIME_ACCESS.get().await.current_time_us() > timeout {
|
||||
if { let guard = TIME_ACCESS.get().await.lock().await; guard.current_time_us() } > timeout {
|
||||
bail!("Timeout waiting for wifi sta connected")
|
||||
}
|
||||
Timer::after(Duration::from_millis(500)).await;
|
||||
}
|
||||
let timeout = TIME_ACCESS.get().await.current_time_us() + max_wait as u64 * 1000;
|
||||
let timeout = { let guard = TIME_ACCESS.get().await.lock().await; guard.current_time_us() } + max_wait as u64 * 1000;
|
||||
while !stack.is_link_up() {
|
||||
if TIME_ACCESS.get().await.current_time_us() > timeout {
|
||||
if { let guard = TIME_ACCESS.get().await.lock().await; guard.current_time_us() } > timeout {
|
||||
bail!("Timeout waiting for wifi link up")
|
||||
}
|
||||
println!("waiting for wifi link up");
|
||||
Timer::after(Duration::from_millis(500)).await;
|
||||
}
|
||||
let timeout = TIME_ACCESS.get().await.current_time_us() + max_wait as u64 * 1000;
|
||||
let timeout = { let guard = TIME_ACCESS.get().await.lock().await; guard.current_time_us() } + max_wait as u64 * 1000;
|
||||
while !stack.is_config_up() {
|
||||
if TIME_ACCESS.get().await.current_time_us() > timeout {
|
||||
if { let guard = TIME_ACCESS.get().await.lock().await; guard.current_time_us() } > timeout {
|
||||
bail!("Timeout waiting for wifi config up")
|
||||
}
|
||||
println!("waiting for wifi config up");
|
||||
Timer::after(Duration::from_millis(100)).await
|
||||
}
|
||||
Ok(stack.clone())
|
||||
}
|
||||
|
||||
pub async fn deep_sleep(&mut self, duration_in_ms: u64) -> ! {
|
||||
RtcSleepConfig::deep();
|
||||
pub fn deep_sleep(&mut self, duration_in_ms: u64, mut rtc: MutexGuard<CriticalSectionRawMutex, Rtc>) -> ! {
|
||||
// Configure and enter deep sleep using esp-hal. Also keep prior behavior where
|
||||
// duration_in_ms == 0 triggers an immediate reset.
|
||||
|
||||
let cur = self.ota.current_ota_state().unwrap();
|
||||
//we made it till here, so fine
|
||||
if cur == OtaImageState::PendingVerify {
|
||||
self.ota
|
||||
.set_current_ota_state(OtaImageState::Valid)
|
||||
.expect("Could not set image to valid");
|
||||
// Mark the current OTA image as valid if we reached here while in pending verify.
|
||||
if let Ok(cur) = self.ota.current_ota_state() {
|
||||
if cur == OtaImageState::PendingVerify {
|
||||
self.ota
|
||||
.set_current_ota_state(OtaImageState::Valid)
|
||||
.expect("Could not set image to valid");
|
||||
}
|
||||
}
|
||||
//unsafe {
|
||||
// //allow early wakeup by pressing the boot button
|
||||
|
||||
if duration_in_ms == 0 {
|
||||
software_reset();
|
||||
} else {
|
||||
loop {
|
||||
info!("todo deepsleep")
|
||||
}
|
||||
// //configure gpio 1 to wakeup on low, reused boot button for this
|
||||
// esp_sleep_enable_ext1_wakeup(
|
||||
// 0b10u64,
|
||||
// esp_sleep_ext1_wakeup_mode_t_ESP_EXT1_WAKEUP_ANY_LOW,
|
||||
// );
|
||||
// esp_deep_sleep(duration_in_ms);
|
||||
let timer = TimerWakeupSource::new(core::time::Duration::from_millis(duration_in_ms));
|
||||
let mut wake_pins: [(&mut dyn RtcPinWithResistors, WakeupLevel); 1] = [(&mut self.wake_gpio1, WakeupLevel::Low)];
|
||||
let ext1 = esp_hal::rtc_cntl::sleep::Ext1WakeupSource::new(&mut wake_pins);
|
||||
rtc.sleep_deep(&[&timer, &ext1]);
|
||||
}
|
||||
//};
|
||||
|
||||
// We should never reach here because sleep_deep never returns, but just in case, reset.
|
||||
software_reset();
|
||||
}
|
||||
|
||||
pub(crate) async fn load_config(&mut self) -> FatResult<PlantControllerConfig> {
|
||||
|
||||
Reference in New Issue
Block a user