diff --git a/src/task/alarm_settings.rs b/src/task/alarm_settings.rs index 08eeb02..c9fb910 100644 --- a/src/task/alarm_settings.rs +++ b/src/task/alarm_settings.rs @@ -20,7 +20,7 @@ use sequential_storage::map::{fetch_item, store_item}; const FLASH_SIZE: usize = 2 * 1024 * 1024; /// # PersistedAlarmTime -/// This struct is used to persist the alarm time in the flash memory. +/// This struct is used to persist the alarm settings in the flash memory. pub struct PersistedAlarmSettings<'a> { flash: Flash<'a, FLASH, Async, { FLASH_SIZE }>, flash_range: Range, diff --git a/src/task/buttons.rs b/src/task/buttons.rs index 0d57473..096a52f 100644 --- a/src/task/buttons.rs +++ b/src/task/buttons.rs @@ -12,9 +12,9 @@ use embassy_sync::channel::Sender; use embassy_time::{with_deadline, Duration, Instant, Timer}; use {defmt_rtt as _, panic_probe as _}; -// Button Manager -// Handles button press, hold, and long hold -// Debounces button press +/// Button Manager +/// Handles button press, hold, and long hold +/// Debounces button press pub struct ButtonManager<'a> { input: Input<'a>, debounce_duration: Duration, diff --git a/src/task/light_effects.rs b/src/task/light_effects.rs index 4f6b686..3a71a17 100644 --- a/src/task/light_effects.rs +++ b/src/task/light_effects.rs @@ -15,14 +15,17 @@ use smart_leds::{brightness, RGB8}; use ws2812_async::Ws2812; use {defmt_rtt as _, panic_probe as _}; +// Number of LEDs in the ring const NUM_LEDS: usize = 16; +/// Manages the neopixel LED ring, including brightness settings for alarm and clock modes. pub struct NeopixelManager { alarm_brightness: u8, clock_brightness: u8, } impl NeopixelManager { + /// Creates a new `NeopixelManager` with default brightness settings. pub fn new() -> Self { Self { alarm_brightness: 90, diff --git a/src/task/orchestrate.rs b/src/task/orchestrate.rs index 2aeeec0..b6e7fd8 100644 --- a/src/task/orchestrate.rs +++ b/src/task/orchestrate.rs @@ -5,7 +5,7 @@ use crate::task::task_messages::*; use core::cell::RefCell; use defmt::*; use embassy_executor::Spawner; -use embassy_futures::select::{select, Either}; +use embassy_futures::select::select; use embassy_rp::peripherals::RTC; use embassy_rp::rtc::DayOfWeek; use embassy_rp::rtc::{DateTime, Rtc}; @@ -22,7 +22,10 @@ pub async fn orchestrator(_spawner: Spawner) { *(STATE_MANAGER_MUTEX.lock().await) = Some(state_manager); } + // init the receiver for the event channel, this is the line we are listening on let event_receiver = EVENT_CHANNEL.receiver(); + + // init the sender for the flash channel let flash_sender = FLASH_CHANNEL.sender(); loop { @@ -52,7 +55,9 @@ pub async fn orchestrator(_spawner: Spawner) { Events::Vbus(usb) => { info!("Vbus event, usb: {}", usb); state_manager.power_state.set_usb_power(usb); - state_manager.power_state.set_battery_level(); + if !state_manager.power_state.get_usb_power() { + VSYS_WAKE_SIGNAL.signal(Commands::VsysWakeUp); + }; DISPLAY_SIGNAL.signal(Commands::DisplayUpdate); } Events::Vsys(voltage) => { @@ -184,7 +189,7 @@ pub async fn scheduler(_spawner: Spawner, rtc_ref: &'static RefCell {} - Either::Second(_) => {} - } + select(downtime_timer, SCHEDULER_WAKE_SIGNAL.wait()).await; } } diff --git a/src/task/power.rs b/src/task/power.rs index 31cfc74..0249e70 100644 --- a/src/task/power.rs +++ b/src/task/power.rs @@ -3,10 +3,11 @@ //! Detremine the supply voltage of the system. use crate::task::resources::{Irqs, UsbPowerResources}; -use crate::task::task_messages::{Events, EVENT_CHANNEL}; +use crate::task::task_messages::{Events, EVENT_CHANNEL, VSYS_WAKE_SIGNAL}; use crate::VsysResources; use defmt::*; use embassy_executor::Spawner; +use embassy_futures::select::select; use embassy_rp::adc::{Adc, Channel, Config}; use embassy_rp::gpio::{Input, Pull}; use embassy_time::{Duration, Timer}; @@ -39,21 +40,26 @@ pub async fn usb_power_detector(_spawner: Spawner, r: UsbPowerResources) { #[embassy_executor::task] pub async fn vsys_voltage_reader(_spawner: Spawner, r: VsysResources) { info!("vsys_voltage task started"); + + // Initialize the ADC and the Vsys input pin. let mut adc = Adc::new(r.adc, Irqs, Config::default()); let vsys_in = r.pin_27; let mut channel = Channel::new_pin(vsys_in, Pull::None); - let sender = EVENT_CHANNEL.sender(); - let refresh_after_secs = 600; // 10 minutes - // wait for the system to settle, before starting the loop -> the adc is not stable immediately - Timer::after(Duration::from_secs(2)).await; + let sender = EVENT_CHANNEL.sender(); + let downtime = Duration::from_secs(600); // 10 minutes loop { + // wait for the system to settle, before reading -> the adc is not stable immediately if we got here after either the usb power was cut the system just started + Timer::after(Duration::from_secs(1)).await; // read the adc value let adc_value = adc.read(&mut channel).await.unwrap(); // reference voltage is 3.3V, and the voltage divider ratio is 2.65. The ADC is 12-bit, so 2^12 = 4096 let voltage = (adc_value as f32) * 3.3 * 2.65 / 4096.0; sender.send(Events::Vsys(voltage)).await; - Timer::after(Duration::from_secs(refresh_after_secs)).await; + + // we either wait for the downtime or until we are woken up early. Whatever comes first, starts the next iteration. + let downtime_timer = Timer::after(downtime); + select(downtime_timer, VSYS_WAKE_SIGNAL.wait()).await; } } diff --git a/src/task/state.rs b/src/task/state.rs index ea7e0a5..cad9f53 100644 --- a/src/task/state.rs +++ b/src/task/state.rs @@ -432,5 +432,6 @@ impl PowerState { pub fn set_usb_power(&mut self, usb_power: bool) { self.usb_power = usb_power; + self.set_battery_level(); } } diff --git a/src/task/task_messages.rs b/src/task/task_messages.rs index b0f91c3..6a05e8b 100644 --- a/src/task/task_messages.rs +++ b/src/task/task_messages.rs @@ -67,8 +67,10 @@ pub enum Commands { SchedulerStop, /// Start the scheduler SchedulerStart, - /// Wake the scheduler early when awaiting the next tick + /// Wake the scheduler early when awaiting the next iteration SchedulerWakeUp, + /// Wake the vsys_voltage_reader task early when awaiting the next iteration + VsysWakeUp, } /// For the events that we want the orchestrator to react to, all state events are of the type Enum Events. @@ -94,3 +96,5 @@ pub static LIGHTFX_STOP_SIGNAL: Signal = Sign /// Signal for the update commands that we want the orchestrator to send to the sound task. pub static SOUND_SIGNAL: Signal = Signal::new(); + +pub static VSYS_WAKE_SIGNAL: Signal = Signal::new(); diff --git a/src/task/time_updater.rs b/src/task/time_updater.rs index 9e288a3..699bc2a 100644 --- a/src/task/time_updater.rs +++ b/src/task/time_updater.rs @@ -15,8 +15,6 @@ //! # populate constant TIME_SERVER_URL //! make sure to have a time_api_config.json file in the config folder formatted as follows: //! ```json -//! // populate constant TIME_SERVER_URL -//! make sure to have a time_api_config.json file in the config folder formatted as follows: //! { //! "time api by zone": { //! "baseurl": "http://worldtimeapi.org/api",